【问题标题】:Swift JSON decoding urlSwift JSON 解码网址
【发布时间】:2021-12-14 02:50:25
【问题描述】:

我开始将我的前端 SwiftUI 项目连接到后端,因此我正在学习如何在 Swift 中进行 API 调用。我首先尝试使用this video 中的代码作为一个可行的示例。但是,我遇到了一个错误,JSONDecoder 无法解码返回的数据。

这里发生了什么?对于这个直率的问题,我深表歉意——我是后端开发的新手。


let url = "https://api.sunrise-sunset.org/json?date=2020-01-01&lat=-74.060&lng=40.7128&form"
getData(from: url)
private func getData(from url: String) {
    let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { data, response, error in
        guard let data = data, error == nil else {
            print("Something Went Wrong...")
            return
        }
        // data is available
        var result: Response?
        do {
            result = try JSONDecoder().decode(Response.self, from: data)
        } catch {
            print("failed to convert \(error.localizedDescription)")
        }
        guard let json = result else {
            return
        }
        print(json.status)
        print(json.results.sunrise)
    })
    task.resume()
}

struct Response: Codable {
    let results: MyResult
    let status: String
}

struct MyResult: Codable {
    let sunrise: String
    let sunset: String
    let solar_noon: String
    let day_length: Int
    let civil_twilight_begin: String
    let nautical_twilight_begin: String
    let nautical_twilight_end: String
    let astronomical_twilight_begin: String
    let astronomical_twilight_end: String
}

请注意,我没有完全按照视频进行操作。我把getData 函数从一个 ViewController 类,因为我认为这无关紧要——我现在不处理任何观点,我也不想这样做。我还冒昧地在 Swift Playground 中测试了代码。不知道会不会有影响。

【问题讨论】:

  • 打印错误而不是 error.localizedDescription。您将获得有关问题所在的更多详细信息。
  • 你在结果中都有字符串元素。

标签: json swift api decode


【解决方案1】:

您的代码中的主要问题是您的 day_length 数据类型。您正在尝试解码Int,而返回的数据是String。除此之外,使用 camelCase 命名结构属性是 Swift 命名约定。匹配 json 所需要做的就是将 JSONDecoder 对象 keyDecodingStrategy 属性设置为 .convertFromSnakeCase。并且在打印解码错误时,您应该打印 error 而不是 cmets 中已经提到的 localizedDescription


struct Response: Codable {
    let results: MyResult
    let status: String
}

struct MyResult: Codable {
    let sunrise: String
    let sunset: String
    let solarNoon: String
    let dayLength: String
    let civilTwilightBegin: String
    let nauticalTwilightBegin: String
    let nauticalTwilightEnd: String
    let astronomicalTwilightBegin: String
    let astronomicalTwilightEnd: String
}

游乐场测试:

let json = """
{"results":{"sunrise":"12:00:01 AM","sunset":"12:00:01 AM","solar_noon":"9:20:25 AM","day_length":"00:00:00","civil_twilight_begin":"12:00:01 AM","civil_twilight_end":"12:00:01 AM","nautical_twilight_begin":"12:00:01 AM","nautical_twilight_end":"12:00:01 AM","astronomical_twilight_begin":"12:00:01 AM","astronomical_twilight_end":"12:00:01 AM"},"status":"OK"}
"""

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let result = try decoder.decode(Response.self, from: Data(json.utf8))
    print(result)
} catch {
    print("Decoding error:", error)
}

这将打印:

响应(结果:MyResult(日出:“12:00:01 AM”,日落:“12:00:01 AM”,solarNoon:“9:20:25 AM”,dayLength:“00:00:00 ",civilTwilightBegin: "12:00:01 AM", nauticalTwilightBegin: "12:00:01 AM", nauticalTwilightEnd: "12:00:01 AM", astronomicalTwilightBegin: "12:00:01 AM", astronomicalTwilightEnd: "12 :00:01 AM"),状态:"OK")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    相关资源
    最近更新 更多