使用 Codable swift 从文件中解析 JSON
Parse JSON from file using Codable swift
我有 JSON 个包含城市的文件
[
{"country":"UA","name":"Hurzuf","_id":707860,"coord":{"lon":34.283333,"lat":44.549999}},
{"country":"RU","name":"Novinki","_id":519188,"coord":{"lon":37.666668,"lat":55.683334}},
{"country":"NP","name":"Gorkhā","_id":1283378,"coord":{"lon":84.633331,"lat":28}},
{"country":"IN","name":"State of Haryāna","_id":1270260,"coord":{"lon":76,"lat":29}},
{"country":"UA","name":"Holubynka","_id":708546,"coord":{"lon":33.900002,"lat":44.599998}},
{"country":"NP","name":"Bāgmatī Zone","_id":1283710,"coord":{"lon":85.416664,"lat":28}},
{"country":"RU","name":"Mar’ina Roshcha","_id":529334,"coord":{"lon":37.611111,"lat":55.796391}},
{"country":"IN","name":"Republic of India","_id":1269750,"coord":{"lon":77,"lat":20}},
{"country":"NP","name":"Kathmandu","_id":1283240,"coord":{"lon":85.316666,"lat":27.716667}},
{"country":"UA","name":"Laspi","_id":703363,"coord":{"lon":33.733334,"lat":44.416668}},
{"country":"VE","name":"Merida","_id":3632308,"coord":{"lon":-71.144997,"lat":8.598333}},
{"country":"RU","name":"Vinogradovo","_id":473537,"coord":{"lon":38.545555,"lat":55.423332}},
{"country":"IQ","name":"Qarah Gawl al ‘Ulyā","_id":384848,"coord":{"lon":45.6325,"lat":35.353889}},
{"country":"RU","name":"Cherkizovo","_id":569143,"coord":{"lon":37.728889,"lat":55.800835}},
{"country":"UA","name":"Alupka","_id":713514,"coord":{"lon":34.049999,"lat":44.416668}},
{"country":"DE","name":"Lichtenrade","_id":2878044,"coord":{"lon":13.40637,"lat":52.398441}},
{"country":"RU","name":"Zavety Il’icha","_id":464176,"coord":{"lon":37.849998,"lat":56.049999}},
{"country":"IL","name":"‘Azriqam","_id":295582,"coord":{"lon":34.700001,"lat":31.75}},
{"country":"IN","name":"Ghūra","_id":1271231,"coord":{"lon":79.883331,"lat":24.766666}}
]
这些只是少数条目,我的文件中有将近 1000 个条目。
我需要应用分页来加载 100 个条目。
我创建了codable
如下
struct Cities: Codable {
let city: [City]?
let pagination: Pagination?
}
struct City: Codable{
let country : String
let name : String
let _id : Int
let coord: [Coordinates]?
}
struct Coordinates: Codable {
let lat : Double?
let lon : Double?
}
struct Pagination: Codable {
let limit, offset: Int?
}
而我的解析方法是这样的,
func getDataFrom(completion: @escaping (Cities?, Error?) -> Void) {
let url = Bundle.main.url(forResource: "cities", withExtension: "json")!
let data = try! Data(contentsOf: url)
do {
let jsonDescription = try JSONDecoder().decode(Cities.self, from: data)
print(jsonDescription)
completion(jsonDescription,nil)
}
catch let jsonError {
print("Json Error:", jsonError)
}
}
当我解析数据时,它进入 catch 块并给出此错误
Json Error: typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))
谁能告诉我我做错了什么。
我需要解析这些数据并使用分页显示在 tableview 上。
提前致谢。
您正在尝试解码一种类型的 Cities.self
,但您的 JSON 是一个数组 - 它以“[”开头并以“]”结尾。您可能想尝试在解码器调用中声明类型 [Cities].self
。
let jsonDescription = try JSONDecoder().decode([City].self, from: data)
编辑:
@Joakim_Danielson 发现了一个问题,你需要解码数组 [City]
而不是 [Cities]
,因为那是你的 JSON 是什么(我编辑了上面的行相应的代码)。
但是还有一个问题:你的结构City
中的属性coord
被声明为数组[Coordinates]?
,但是你的JSON没有在“坐标”键中有一个数组 - 只是一个实例。
尝试更改您的 coord
属性,使其成为 Coordinate?
.
的类型
我有 JSON 个包含城市的文件
[
{"country":"UA","name":"Hurzuf","_id":707860,"coord":{"lon":34.283333,"lat":44.549999}},
{"country":"RU","name":"Novinki","_id":519188,"coord":{"lon":37.666668,"lat":55.683334}},
{"country":"NP","name":"Gorkhā","_id":1283378,"coord":{"lon":84.633331,"lat":28}},
{"country":"IN","name":"State of Haryāna","_id":1270260,"coord":{"lon":76,"lat":29}},
{"country":"UA","name":"Holubynka","_id":708546,"coord":{"lon":33.900002,"lat":44.599998}},
{"country":"NP","name":"Bāgmatī Zone","_id":1283710,"coord":{"lon":85.416664,"lat":28}},
{"country":"RU","name":"Mar’ina Roshcha","_id":529334,"coord":{"lon":37.611111,"lat":55.796391}},
{"country":"IN","name":"Republic of India","_id":1269750,"coord":{"lon":77,"lat":20}},
{"country":"NP","name":"Kathmandu","_id":1283240,"coord":{"lon":85.316666,"lat":27.716667}},
{"country":"UA","name":"Laspi","_id":703363,"coord":{"lon":33.733334,"lat":44.416668}},
{"country":"VE","name":"Merida","_id":3632308,"coord":{"lon":-71.144997,"lat":8.598333}},
{"country":"RU","name":"Vinogradovo","_id":473537,"coord":{"lon":38.545555,"lat":55.423332}},
{"country":"IQ","name":"Qarah Gawl al ‘Ulyā","_id":384848,"coord":{"lon":45.6325,"lat":35.353889}},
{"country":"RU","name":"Cherkizovo","_id":569143,"coord":{"lon":37.728889,"lat":55.800835}},
{"country":"UA","name":"Alupka","_id":713514,"coord":{"lon":34.049999,"lat":44.416668}},
{"country":"DE","name":"Lichtenrade","_id":2878044,"coord":{"lon":13.40637,"lat":52.398441}},
{"country":"RU","name":"Zavety Il’icha","_id":464176,"coord":{"lon":37.849998,"lat":56.049999}},
{"country":"IL","name":"‘Azriqam","_id":295582,"coord":{"lon":34.700001,"lat":31.75}},
{"country":"IN","name":"Ghūra","_id":1271231,"coord":{"lon":79.883331,"lat":24.766666}}
]
这些只是少数条目,我的文件中有将近 1000 个条目。 我需要应用分页来加载 100 个条目。
我创建了codable
如下
struct Cities: Codable {
let city: [City]?
let pagination: Pagination?
}
struct City: Codable{
let country : String
let name : String
let _id : Int
let coord: [Coordinates]?
}
struct Coordinates: Codable {
let lat : Double?
let lon : Double?
}
struct Pagination: Codable {
let limit, offset: Int?
}
而我的解析方法是这样的,
func getDataFrom(completion: @escaping (Cities?, Error?) -> Void) {
let url = Bundle.main.url(forResource: "cities", withExtension: "json")!
let data = try! Data(contentsOf: url)
do {
let jsonDescription = try JSONDecoder().decode(Cities.self, from: data)
print(jsonDescription)
completion(jsonDescription,nil)
}
catch let jsonError {
print("Json Error:", jsonError)
}
}
当我解析数据时,它进入 catch 块并给出此错误
Json Error: typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))
谁能告诉我我做错了什么。 我需要解析这些数据并使用分页显示在 tableview 上。
提前致谢。
您正在尝试解码一种类型的 Cities.self
,但您的 JSON 是一个数组 - 它以“[”开头并以“]”结尾。您可能想尝试在解码器调用中声明类型 [Cities].self
。
let jsonDescription = try JSONDecoder().decode([City].self, from: data)
编辑:
@Joakim_Danielson 发现了一个问题,你需要解码数组 [City]
而不是 [Cities]
,因为那是你的 JSON 是什么(我编辑了上面的行相应的代码)。
但是还有一个问题:你的结构City
中的属性coord
被声明为数组[Coordinates]?
,但是你的JSON没有在“坐标”键中有一个数组 - 只是一个实例。
尝试更改您的 coord
属性,使其成为 Coordinate?
.