【问题标题】:Swift JSONDecoder throws an error during buildSwift JSONDecoder 在构建期间抛出错误
【发布时间】:2021-11-05 15:52:55
【问题描述】:

你好,我有一个像这样的 json 文件

}
"CYYZ": {
        "icao": "CYYZ",
        "iata": "YYZ",
        "name": "Lester B. Pearson International Airport",
        "city": "Toronto",
        "state": "Ontario",
        "country": "CA",
        "elevation": 569,
        "latitude": 43.6772003174,
        "longitude": -79.6305999756,
        "tz": "America\/Toronto"
    },
    "CYZD": {
        "icao": "CYZD",
        "iata": "YZD",
        "name": "Downsview Airport",
        "city": "Toronto",
        "state": "Ontario",
        "country": "CA",
        "elevation": 652,
        "latitude": 43.7425003052,
        "longitude": -79.4655990601,
        "tz": "America\/Toronto"
    },
    "CYZE": {
        "icao": "CYZE",
        "iata": "YZE",
        "name": "Gore Bay Manitoulin Airport",
        "city": "Gore Bay",
        "state": "Ontario",
        "country": "CA",
        "elevation": 635,
        "latitude": 45.8852996826,
        "longitude": -82.5678024292,
        "tz": "America\/Toronto"
    }
}

我做了一个这样的结构

struct AirportData: Codable{
    let iata: String
    let name: String
    let longitude: Double
    let latitude: Double
}

我编写了以下代码来设置 url 并使其成为字符串,然后我用它来解码 json

    override func viewDidLoad() {
            super.viewDidLoad()

//make url for file path
    guard let jsonURL = Bundle(for: type(of: self)).path(forResource: "airports", ofType: "json") else {
                return
            }
            //make url a string
            guard let jsonString = try? String(contentsOf: URL(fileURLWithPath:jsonURL), encoding: String.Encoding.utf8) else {
                return
            }
            
            var airports: AirportData?
            do{
                airports = try JSONDecoder().decode(AirportData.self, from: Data(jsonString.utf8))
            }
            catch{
                print("error occured when decoding")
            }
            
            
            guard let results = airports else {
                return
            }
            
            print(results.iata)
                
            }

我不断收到“解码时出错”

请帮助我遵循this 教程,但没有得到相同的结果,也许我的结构是错误的。谢谢。

【问题讨论】:

    标签: ios json swift


    【解决方案1】:

    首先你的json不正确,第一个括号应该是“{”而不是“}”。

    第二,你的数据结构不正确,用这个:

    struct AirportData: Codable {
        let icao, iata, name, city: String
        let state, country: String
        let elevation: Int
        let latitude, longitude: Double
        let tz: String
    }
    
    typealias Response = [String: AirportData] 
    

    第三,你的viewDidLoad 代码是一团糟。使用类似这样的方法来获取您的数据:

    override func viewDidLoad() {
        super.viewDidLoad()
        var airports: [String:AirportData]?
        if let url = Bundle.main.url(forResource: "airports", withExtension: "json") {
            do {
                let data = try Data(contentsOf: url)
                airports = try JSONDecoder().decode(Response.self, from: data)
                print("\n---> airports: \(airports) \n")
            } catch {
                print("error occured when decoding: \(error)")
            }
        }
    }
    

    【讨论】:

    • 有时强制解包比静默失败要好。如果 OP 确定他已将该文件包含在包中,那么如果该文件不存在,则该文件将崩溃,这将更有帮助。 let url = Bundle.main.url(forResource: "airports", withExtension: "json")!
    • 是的,你可以这样做,但在这种情况下,最好只输入一个 else {...} 并显示警报或其他内容,而不是让应用程序完全崩溃。
    • 提醒开发者? kkkk 他应该知道文件是否不在捆绑包中。没有任何东西可以显示给用户。
    • 可能是“请联系开发者,他/她忘记包含文件”,哈哈
    • kkk 这正是我的意思。在这些情况下需要致命错误。您不想在未将文件添加到捆绑包的情况下发布应用程序。
    猜你喜欢
    • 2020-07-14
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 2020-05-22
    相关资源
    最近更新 更多