Swift 4中使用Decodable访问嵌套JSON的技术问题
解决Swift解析嵌套JSON数组的问题
嘿,我来帮你搞定这个嵌套JSON数组解析的问题!首先得搞清楚你要处理的JSON结构,然后通过创建顶层解析模型来拿到目标数组,具体步骤如下:
先明确问题背景
你已经定义了StarWarsPeople模型,但卡在了如何从JSON的嵌套数组里取出数据来初始化这些对象。假设你调用的是Star Wars的API,返回的JSON结构大概是这样的(核心是数组嵌套在results字段里):
{ "count": 82, "next": "https://swapi.dev/api/people/?page=2", "previous": null, "results": [ { "name": "Luke Skywalker", "height": "172", "mass": "77", "hair_color": "blond", // 其他对应字段... } ] }
步骤1:创建顶层响应模型
因为目标数组是嵌套在顶层字典里的,所以我们需要先定义一个承接整个JSON响应的Decodable结构,这样才能顺利拿到里面的数组:
struct StarWarsResponse: Decodable { let results: [StarWarsPeople] }
步骤2:完善APIClient的解析逻辑
接下来修改你的StarWarsPeopleAPIClient,发起网络请求后用JSONDecoder先解析整个顶层响应,再取出里面的results数组:
class StarWarsPeopleAPIClient { class func fetchPeople(completion: @escaping ([StarWarsPeople]?, Error?) -> Void) { // 替换成你实际的API地址 guard let url = URL(string: "https://swapi.dev/api/people/") else { completion(nil, NSError(domain: "Invalid URL", code: 0, userInfo: [NSLocalizedDescriptionKey: "URL格式错误"])) return } URLSession.shared.dataTask(with: url) { data, _, error in // 先处理网络错误 if let error = error { completion(nil, error) return } // 确保拿到数据 guard let responseData = data else { completion(nil, NSError(domain: "Data Error", code: 0, userInfo: [NSLocalizedDescriptionKey: "未获取到数据"])) return } do { // 解析顶层响应 let swResponse = try JSONDecoder().decode(StarWarsResponse.self, from: responseData) // 取出嵌套的人物数组,传给回调 completion(swResponse.results, nil) } catch let decodingError { completion(nil, decodingError) } }.resume() } }
额外的小修正
注意你的StarWarsPeople里的weight属性,Star Wars API对应的字段是mass,如果不想改属性名,需要添加CodingKeys来做字段映射:
class StarWarsPeople: Decodable { var name: String? var height: String? var weight: String? var hair_color: String? var skin_color: String? var eye_color: String? var birth_year: String? var gender: String? // 字段映射,解决属性名和API字段名不一致的问题 enum CodingKeys: String, CodingKey { case name, height, hair_color, skin_color, eye_color, birth_year, gender case weight = "mass" } }
另外建议把StarWarsPeople改成struct,值类型在处理数据模型时更安全,而且默认就能自动合成Decodable的实现,不需要额外代码。
内容的提问来源于stack exchange,提问作者Sara
相关产品推荐
相关产品推荐

