尝试通过 json 解码器解码 json 时出错
Getting error while trying to decode json through jsondecoder
这是我的json
我正在尝试使用 JSONDecoder 进行解码,但由于无法做到这一点而遇到困难。有人可以帮助我了解什么结构以及如何解码吗?
{
"Afghanistan": [
{
"city": "Kabul",
"lat": "34.5167",
"lng": "69.1833",
"state": "Kābul",
"country": "Afghanistan"
},
{
"city": "Karukh",
"lat": "34.4868",
"lng": "62.5918",
"state": "Herāt",
"country": "Afghanistan"
},
{
"city": "Zarghūn Shahr",
"lat": "32.85",
"lng": "68.4167",
"state": "Paktīkā",
"country": "Afghanistan"
}
],
"Albania": [
{
"city": "Tirana",
"lat": "41.3275",
"lng": "19.8189",
"state": "Tiranë",
"country": "Albania"
},
{
"city": "Pukë",
"lat": "42.0333",
"lng": "19.8833",
"state": "Shkodër",
"country": "Albania"
}
]}
你有什么解码建议?
我正在尝试这个
let locationData: Countries = load("Countries.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
struct Country: Codable, Identifiable {
var id = UUID()
let city, lat, lng: String
let state: String?
let country: String
}
typealias Countries = [String: [Country]]
但是出现这个错误
Couldn't parse Countries.json as Dictionary>:
keyNotFound(CodingKeys(stringValue: "id", intValue: nil),
Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue:
"Albania", intValue: nil), _JSONKey(stringValue: "Index 0", intValue:
0)], debugDescription: "No value associated with key
CodingKeys(stringValue: \"id\", intValue: nil) (\"id\").",
underlyingError: nil)):
由于 属性 id
不是 json 的一部分,您需要通过向 Country
[= 添加 CodingKey 枚举来定义解码器应解码的属性14=]
enum CodingKeys: String, CodingKey {
case city, lat, lng, state, country
}
CodingKey 枚举还让您有机会为您的结构属性使用更好的名称,并将它们映射到枚举中的 json 键。
struct Country: Codable, Identifiable {
var id = UUID()
let city: String
let latitude: String
let longitude: String
let state: String?
let country: String
enum CodingKeys: String, CodingKey {
case city
case latitude = "lat"
case longitude = "lng"
case state, country
}
}
这是错误的相关部分:keyNotFound(CodingKeys(stringValue: "id", intValue: nil)
。它告诉您它正在每个 JSON 对象中寻找一个 "id" 键,但没有找到它。
它正在寻找一个 id,因为结构的 Codable
协议的默认实现会尝试反序列化您定义的所有属性。您定义了 var id
属性,所以它正在寻找那个。
由于您不想反序列化 id 属性,因此您需要自定义您的结构,使其不使用默认实现。有关如何执行此操作的文档在此处:Encoding and Decoding Custom Types
在你的情况下,你只需要在你的结构中定义一个 CodingKeys
枚举,这样它就知道要查找哪些键:
enum CodingKeys: String, CodingKey {
case city, lat, lng, state, country
}
这是我的json 我正在尝试使用 JSONDecoder 进行解码,但由于无法做到这一点而遇到困难。有人可以帮助我了解什么结构以及如何解码吗?
{
"Afghanistan": [
{
"city": "Kabul",
"lat": "34.5167",
"lng": "69.1833",
"state": "Kābul",
"country": "Afghanistan"
},
{
"city": "Karukh",
"lat": "34.4868",
"lng": "62.5918",
"state": "Herāt",
"country": "Afghanistan"
},
{
"city": "Zarghūn Shahr",
"lat": "32.85",
"lng": "68.4167",
"state": "Paktīkā",
"country": "Afghanistan"
}
],
"Albania": [
{
"city": "Tirana",
"lat": "41.3275",
"lng": "19.8189",
"state": "Tiranë",
"country": "Albania"
},
{
"city": "Pukë",
"lat": "42.0333",
"lng": "19.8833",
"state": "Shkodër",
"country": "Albania"
}
]}
你有什么解码建议?
我正在尝试这个
let locationData: Countries = load("Countries.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
struct Country: Codable, Identifiable {
var id = UUID()
let city, lat, lng: String
let state: String?
let country: String
}
typealias Countries = [String: [Country]]
但是出现这个错误
Couldn't parse Countries.json as Dictionary>: keyNotFound(CodingKeys(stringValue: "id", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Albania", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"id\", intValue: nil) (\"id\").", underlyingError: nil)):
由于 属性 id
不是 json 的一部分,您需要通过向 Country
[= 添加 CodingKey 枚举来定义解码器应解码的属性14=]
enum CodingKeys: String, CodingKey {
case city, lat, lng, state, country
}
CodingKey 枚举还让您有机会为您的结构属性使用更好的名称,并将它们映射到枚举中的 json 键。
struct Country: Codable, Identifiable {
var id = UUID()
let city: String
let latitude: String
let longitude: String
let state: String?
let country: String
enum CodingKeys: String, CodingKey {
case city
case latitude = "lat"
case longitude = "lng"
case state, country
}
}
这是错误的相关部分:keyNotFound(CodingKeys(stringValue: "id", intValue: nil)
。它告诉您它正在每个 JSON 对象中寻找一个 "id" 键,但没有找到它。
它正在寻找一个 id,因为结构的 Codable
协议的默认实现会尝试反序列化您定义的所有属性。您定义了 var id
属性,所以它正在寻找那个。
由于您不想反序列化 id 属性,因此您需要自定义您的结构,使其不使用默认实现。有关如何执行此操作的文档在此处:Encoding and Decoding Custom Types
在你的情况下,你只需要在你的结构中定义一个 CodingKeys
枚举,这样它就知道要查找哪些键:
enum CodingKeys: String, CodingKey {
case city, lat, lng, state, country
}