SwiftJSON解码url
Swift JSON decoding url
我开始将我的前端 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
class 因为我认为这无关紧要——此时我不处理任何观点,我也不想处理任何观点。我还冒昧地在 Swift Playground 中测试了代码。不知道会不会有影响。
代码中的主要问题是 day_length
数据类型。您正在尝试解码 Int
,而返回的数据是 String
。除此之外,Swift 命名约定使用驼峰式命名结构属性。要匹配 json,您需要做的就是将 JSONDecoder 对象 keyDecodingStrategy
属性 设置为 .convertFromSnakeCase
。在打印解码错误时,您应该打印 error
而不是评论中已经提到的 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)
}
这将打印:
Response(results: MyResult(sunrise: "12:00:01 AM", sunset: "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"), status: "OK")
我开始将我的前端 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
class 因为我认为这无关紧要——此时我不处理任何观点,我也不想处理任何观点。我还冒昧地在 Swift Playground 中测试了代码。不知道会不会有影响。
代码中的主要问题是 day_length
数据类型。您正在尝试解码 Int
,而返回的数据是 String
。除此之外,Swift 命名约定使用驼峰式命名结构属性。要匹配 json,您需要做的就是将 JSONDecoder 对象 keyDecodingStrategy
属性 设置为 .convertFromSnakeCase
。在打印解码错误时,您应该打印 error
而不是评论中已经提到的 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)
}
这将打印:
Response(results: MyResult(sunrise: "12:00:01 AM", sunset: "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"), status: "OK")