Swift解码API返回JSON并将商品提取到数组的实现问题
问题核心原因
你解码得到的result是Root结构体实例,而productArray的类型是[Product],二者类型不匹配,无法直接赋值。
具体修改方案
只需要修改解码成功后给productArray赋值的逻辑即可:从Root的items数组中,提取每个元素的product属性,重新组成Product类型的数组再赋值。
把原来的代码:
DispatchQueue.main.async { productArray = result }
替换为:
DispatchQueue.main.async { productArray = result.items.map { $0.product } }
额外优化建议
- 调试阶段可以把catch块的错误打印得更清晰,方便定位其他可能的解码问题:
catch { print("解码失败:\(error.localizedDescription),详细错误:\(error)") }
- 如果接口返回的数据可能存在
product为空的情况,可以把Item结构体里的product属性改为可选类型,避免整个解码失败。
修改后完整可运行代码
// Models struct Root: Codable { let items: [Item] } struct Item: Codable { let product: Product } struct Product: Codable { let name: String } //Product array var productArray: [Product] = [] // URL and data fetching let urlString: String = "https://api.jsonbin.io/b/60832bec4465377a6bc6b6e6" func fetchData() { guard let url = URL(string: urlString) else { return } let task = URLSession.shared.dataTask(with: url) { data, _, error in guard let data = data, error == nil else { return } do { let result = try JSONDecoder().decode(Root.self, from: data) DispatchQueue.main.async { productArray = result.items.map { $0.product } // 可打开下面的注释验证结果 // print("获取到商品数量:\(productArray.count)") // productArray.forEach { print("商品名:\($0.name)") } } } catch { print("解码失败:\(error)") } } task.resume() } fetchData()
内容的提问来源于stack exchange,提问作者Nikolai
相关产品推荐
相关产品推荐

