Swift - JSON解码返回空数组

Posted

技术标签:

【中文标题】Swift - JSON解码返回空数组【英文标题】:Swift - JSON decoding returning empty array 【发布时间】:2019-07-11 18:50:47 【问题描述】:

对于我的第一个 Swift UIKit 应用程序,我正在尝试解析一些 JSON 数据并使用它来填充 UITableView。理想情况下,表格视图会随着 JSON 的更改而更新,但目前这并不是完全必要的,因为 JSON 不会经常更改。

但我在解析 JSON 时遇到了一些问题 - 我似乎得到了一个空数组...

我的主视图控制器中的代码

import Foundation
import UIKit

//TODO - JSON

struct Visualisation: Codable 
    var id: Int
    let name, info, url_name, tags: String


/*
JSON:

[
    
        "id": 0,
        "name": "Two Body Collision",
        "info": "A 2D body collision under the elastic collision assumption",
        "url_name": "https://www.imperialvisualisations.com/visualisations/two-body-collision/two-body-collision/",
        "tags": "Physics, Mechanics"

    ,
    
        "id": 1,
        "name": "Waves in Dielectrics",
        "info": "The effect of incidence angle & refractive index of dielectric on reflection & transmission",
        "url_name": "https://www.imperialvisualisations.com/visualisations/2d-and-3d-coordinate-systems/2d-polar-coordinates/",
        "tags": "Physics, Maths, Matrices, Linear algebra"
    
]

This is the structure I am aiming for:

var visualisations: [Visualisation] = [
    .init(id:0, name: "Two Body Collision", info: "A 2D body collision under the elastic collision assumption", url_name: "https://www.imperialvisualisations.com/visualisations/two-body-collision/two-body-collision/", tags: "Physics, Mechanics"),
    .init(id:2, name: "Waves in Dielectrics", info: "The effect of incidence angle & refractive index of dielectric on reflection & transmission", url_name: "https://www.imperialvisualisations.com/visualisations/single-wave-in-3d/boundry-conditions/", tags: "Physics, Electromagnetism, Light, Refractive index, Angle of incidence")
]

 */

class ViewController: UIViewController 

    @IBOutlet weak var tableView: UITableView!


    var visualisations = [Visualisation]()

    override func viewDidLoad() 
        super.viewDidLoad()

        guard let url = URL(string: "https://api.myjson.com/bins/1ao7in") else  fatalError("JSON URL not found") 

        URLSession.shared.dataTask(with: url)  (data, _, _) in
            guard let data = data else  fatalError("JSON data not loaded") 

            guard let decodedVisualisations = try? JSONDecoder().decode([Visualisation].self, from: data) else  fatalError("Failed to decode JSON")

            DispatchQueue.main.async
                self.visualisations = decodedVisualisations
            

        .resume()

        print("visualisations")
        print(visualisations)

        tableView.delegate = self
        tableView.dataSource = self


        navigationController?.navigationBar.prefersLargeTitles = true
        title = "Visualisations"

    



extension ViewController: UITableViewDataSource, UITableViewDelegate 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return visualisations.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        //visualisation at row in view
        let visualisation = visualisations[indexPath.row]
        //recast! ??
        let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as! TableViewCell

        cell.setCell(visualisation: visualisation)

        //set Cell just sets the elements of the table cell in another file

        return cell

    



我没有收到任何错误消息,但是解码似乎对“可视化”数组没有任何作用。

任何帮助将不胜感激 - 谢谢。

【问题讨论】:

没有收到任何错误消息,因为您忽略了解码错误。添加do - catch 块,删除guardcatch 子句中tryprint(error) 后面的问号。 您是否尝试在某处添加显式表重新加载?例如,就在self.visualisations = decodedVisualisations 行之后。 【参考方案1】:

根据@vadian 的评论,这很好用。

struct Visualisation: Codable 
    var id: Int
    let name, info, url_name, tags: String


class ViewController: UIViewController 

    var visualisations = [Visualisation]()

    override func viewDidLoad() 
        super.viewDidLoad()

        guard let url = URL(string: "https://api.myjson.com/bins/1ao7in") else  fatalError("JSON URL not found") 

        URLSession.shared.dataTask(with: url)  (data, _, _) in
            guard let data = data else  fatalError("JSON data not loaded") 

            do 
                let decodedVisualisations = try JSONDecoder().decode([Visualisation].self, from: data)
                self.visualisations = decodedVisualisations
             catch let error 
                debugPrint(error.localizedDescription)
            
        .resume()

    

【讨论】:

请永远不要建议在 JSONDe/-Encoder 捕获块中打印 error.localizedDescription。您将收到一条毫无意义的通用错误消息。始终打印error 实例以获得全面的错误描述。顺便说一句,error 自 Swift 3 以来在 catch 块中隐式可用,let error 是多余的。

以上是关于Swift - JSON解码返回空数组的主要内容,如果未能解决你的问题,请参考以下文章

返回一个空的 JSON 数组导致 Swift 中的越界错误

在 Swift iOS 中解码的 PHP JSON 返回空值

Swift - 解码数组 JSON 数据的数组

Swift Json 解码不确定传入数据

Swift 4 JSON 解码根数组

如何解码包含数组 Swift 4 的 JSON 文件?