SwiftUI调用API时控制台提示数据格式错误的排查与解决
问题排查与解决方案
核心错误原因
你调用的https://dummyjson.com/products接口返回的JSON结构并非直接的Product数组,而是一个包含products字段的外层对象,示例结构如下:
{ "products": [ {"id": 1, "name": "...", ...}, ... ], "total": 100, "skip": 0, "limit": 30 }
而你的代码直接尝试解码[Product].self,这就导致了解码格式不匹配的错误。
具体修复步骤
1. 添加根响应模型
创建一个匹配API返回结构的根模型:
struct ProductResponse: Decodable { let products: [Product] }
2. 修改解码逻辑
在fetchProducts方法中,将解码目标改为ProductResponse.self,再提取内部的products数组:
do { let response = try JSONDecoder().decode(ProductResponse.self, from: data) DispatchQueue.main.async { self.products = response.products } } catch { // 打印完整错误信息,方便排查细节 print("解码错误详情:", error) print(error.localizedDescription) }
3. 修正拼写错误
代码中存在视图名称拼写错误:ProuctDetail → 改为ProductDetail,否则NavigationLink会找不到目标视图。
4. 优化错误排查技巧
以后遇到解码错误时,不要只打印localizedDescription,直接打印error本身可以得到更详细的信息,比如哪个字段不匹配、类型错误等,能快速定位问题。
修复后的核心代码片段
struct ProductResponse: Decodable { let products: [Product] } // ... func fetchProducts() { guard let url = URL(string: "https://dummyjson.com/products") else { return } let request = URLRequest(url: url) URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print(error.localizedDescription) return } if let data = data { do { let decodedResponse = try JSONDecoder().decode(ProductResponse.self, from: data) DispatchQueue.main.async { self.products = decodedResponse.products } } catch { print("解码错误详情:", error) print(error.localizedDescription) } } }.resume() } // 修正后的视图名称 struct ProductDetail: View { var product: Product var body: some View { // 原有视图代码保持不变 VStack { AsyncImage(url: URL(string: product.image)) { image in image.resizable() } placeholder: { ProgressView() } .scaledToFit() Text(product.name) .font(.largeTitle) .padding() Text(product.description) .padding() Text("$\(product.price, specifier: \"%.2f\")") .font(.title) .foregroundColor(.green) .padding() Spacer() } } }
内容的提问来源于stack exchange,提问作者MustachePotet
相关产品推荐
相关产品推荐

