【问题标题】:Couldn't use JSON Data in an viewController extension?无法在 viewController 扩展中使用 JSON 数据?
【发布时间】:2020-04-27 07:23:22
【问题描述】:

谁能告诉我我在这里做错了什么? 我无法将 JSON 数据从 URLSession.shared.dataTask 传递到外部扩展 也不能带来 func numberOfSections .. 等在 URLSession.shared.dataTask 中使用

感谢您的帮助,感谢您的宝贵时间。

斯威夫特

struct getSubData: 可解码 { 让 id: Int 让名称:字符串 }

结构部分:可解码{ 让 id: Int 让名称:字符串 让子数据:[getSubData] }

类 indexViewController: UIViewController { @IBOutlet 弱 var tableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()
    let url = "https://nabulsi.com/nabulsi_app/main_sections_v4.json"
                         let urlObj = URL(string: url)
                         URLSession.shared.dataTask(with: urlObj!){(data, response, error) in
                             do {
                                 let sections = try JSONDecoder().decode([Section].self, from: data!)
                                for section in sections {
                                    print(section.name)
                                    let sectionName = section.name
                                    for data in section.subData {
                                        print(data.name)
                                        let subSectionName = data.name
                                    }
                                }
                             } catch {
                                 print("We got an error")
                             }
                         }.resume()
}

}

扩展 indexViewController: UITableViewDataSource, UITableViewDelegate {

func numberOfSections(in tableView: UITableView) -> Int {
    return sectionName.count

}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return sectionName[section].subSectionName?.count ?? 0

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = sectionName[indexPath.section].subSectionName?[indexPath.row]

    return cell
}

}

【问题讨论】:

    标签: arrays json uitableview swift5


    【解决方案1】:

    JsonDecoder 类没有机会解析您的数据,因为从服务器接收到 JSON 文本不是有效格式

    这是您的端点,在网络浏览器中打开它:https://nabulsi.com/nabulsi_app/main_sections_v4.json

    这里是 JSON 验证器工具:https://jsonlint.com

    复制并粘贴以验证您对名为 jsonlintJSON 验证器工具的服务器响应,您将看看你哪里错了。

    这可能不是你的错。如果您不是自己编写的,那么这与您的后端开发人员有关。联系他修复 JSON 格式。解决问题后请通知我。如果它仍然无法按您的预期工作,我将修复您的解析代码。

    • 编辑:修复问题后,相关代码如下:

    [0] - 分配给局部变量的解析 json 值。

    class indexViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    var sections: [Section] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let url = "https://nabulsi.com/nabulsi_app/main_sections_v4.json"
        let urlObj = URL(string: url)
        URLSession.shared.dataTask(with: urlObj!){(data, response, error) in
            do {
                let sections = try JSONDecoder().decode([Section].self, from: data!)
                self.sections = sections // [0]
    
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
    
            } catch {
                print("We got an error")
            }
        }.resume()
      }
    }
    
    • 查看代码并按照以下简要说明进行操作:

    [1] - 从本地数组返回节中的每一行

    [2] - 将名称变量分配给当前行的标签

    [3] - 将名称变量分配给当前部分的标题

    extension indexViewController: UITableViewDataSource, UITableViewDelegate {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return sections.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let subDatas = sections[section].subData // [1]
        return subDatas.count ?? 0
    }
    
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    
        // [2]
        let currentSection = sections[indexPath.section]
        let currentSubdata = currentSection.subData[indexPath.row]
        cell.textLabel?.text = currentSubdata.name
    
        return cell
    }
    
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 40))
        view.backgroundColor = #colorLiteral(red: 1, green: 0.3653766513, blue: 0.1507387459, alpha: 1)
    
        let lbl = UILabel(frame: CGRect(x: 0, y: 0, width: view.frame.width - 15, height: 40))
        lbl.font = UIFont.systemFont(ofSize: 20)
        lbl.text = sections[section].name // [3]
        lbl.textAlignment = .right
        view.addSubview(lbl)
    
        return view
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 40
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 40
      }
    }
    

    编码愉快! =]

    【讨论】:

    • 但是:在循环中打印(for section in section)工作正常!我只需要在tableView中使用返回的JSON数据
    • 好的,如果你已经从 URLSession 主体之外存储了返回的 JSON 数据,你必须通知表视图重新加载:'新数据在这里'。你有一个 tableView 出口变量吗?例如@IBOutlet tableView:UITableView!如果有 tableView 出口,请在 URLSession 任务中的 do { } 块中的 for 循环末尾添加此行: DispatchQueue.main.async { tblView.reloadData() }
    • 如果你没有出口,但是,如果你有机会从 GitHub 分享你的代码给我,我会解决这个问题,你会更好地理解解决方案。
    • 问题是JSON解析后,你没有分配给你的局部变量数组'sections',之后,你没有正确使用它,section中的实际值和这是行。为了清晰的编码,也许您可​​以更改变量名称,例如,将“sections”数组重命名为“sectionArray”。
    【解决方案2】:

    只需将 Array 部分放在函数之外。将其保留为您的控制器的财产。

    class indexViewController: UIViewController { 
    
      @IBOutlet weak var tableView: UITableView!
      var sections: [Section] = []
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        let url = "https://nabulsi.com/nabulsi_app/main_sections_v4.json"
        let urlObj = URL(string: url)
        URLSession.shared.dataTask(with: urlObj!) {
         [weak self](data, response, error) in
         do {
              self?.sections = try JSONDecoder().decode([Section].self, from: data!)
              for section in sections {
                //your code goes here                         
              }
        } 
        catch {
          print("We got an error")
        }
      }.resume()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多