无法在 viewController 扩展中使用 JSON 数据?

Couldn't use JSON Data in an viewController extension?

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

感谢任何帮助,感谢您抽出宝贵时间。

Swift

结构getSubData:可解码{ 让 id: Int 让名字:字符串 }

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

class indexViewController: UIViewController { @IBOutlet weak 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
}

}

只需将 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()
}

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

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

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

复制并粘贴以验证您的服务器对名为 [=]JSON 验证器工具 的响应34=]jsonlint,你就会看到你哪里错了。

可能这不是你的错。如果您不是自己编写,则与您的后端开发人员有关。联系他修复 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] - Return 部分中的每一行,来自本地数组

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

[3] - 将名称变量分配给当前部分 header

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
  }
}

祝您编程愉快! =]