SwiftUI解码嵌套JSON返回nil,求排查问题
问题排查与修复方案
看起来你遇到的核心问题是网络请求根本没有被触发,再加上一些错误处理和UI细节的缺失,导致始终拿到nil。下面一步步帮你解决:
1. 最关键的问题:没有发起网络请求
你的ProductsList类里定义了fetchProducts()方法,但在ContentView中,你只是创建了它的实例,却从来没有调用这个方法去发起请求!这就导致prods一直保持初始值nil。
修复:在视图出现时触发请求
修改ContentView,在onAppear回调中调用请求方法:
struct ContentView: View { @ObservedObject var decodedProducts = ProductsList() // 修正变量命名,符合Swift小写开头的规范 var body: some View { VStack{ HStack{ Text("Pasta: ") Text(decodedProducts.prods?.products.pasta.description ?? "Loading...") .fontWeight(.bold) .foregroundColor(.red) } HStack{ Text("Pizza: ") Text(decodedProducts.prods?.products.pizza.description ?? "Loading...") .fontWeight(.bold) .foregroundColor(.blue) } HStack{ Text("Apples: ") Text(decodedProducts.prods?.products.apples.description ?? "Loading...") .fontWeight(.bold) .foregroundColor(.green) } } .padding() .onAppear { decodedProducts.fetchProducts() // 新增:视图出现时发起网络请求 } } }
2. 完善NetworkController的错误处理
原代码的错误处理非常不完善:如果网络出错、没有返回数据或者解码失败,都不会调用completion,也看不到具体的错误原因,很难排查问题。
修复:增强错误处理和日志
struct NetworkController { static func fetchProducts(completion: @escaping ((ProductWrapper?) -> Void)) { guard let url = URL(string: "http://localhost:1234/index.json") else { print("❌ 无效的URL") completion(nil) return } URLSession.shared.dataTask(with: url) { data, response, error in // 统一在主线程处理UI相关的回调 DispatchQueue.main.async { if let error = error { print("❌ 网络请求错误:\(error)") completion(nil) return } guard let data = data else { print("❌ 没有接收到服务器返回的数据") completion(nil) return } do { let prods = try JSONDecoder().decode(ProductWrapper.self, from: data) completion(prods) } catch { // 打印完整的解码错误,方便定位问题(比如键名不匹配、类型错误) print("❌ JSON解码错误:\(error)") completion(nil) } } }.resume() } }
3. 验证JSON与结构体的匹配性
仔细核对你的JSON键名和Product结构体的属性:
你的JSON里的键是"pasta"、"pizza"、"apples"、"sausages"、"potatoes"、"cucmbers"、"oranges",和结构体里的属性完全一致,这部分是没问题的。但如果后续修改JSON时出现拼写错误(比如把cucmbers改成cucumbers),一定要同步修改结构体的属性名,否则会解码失败。
最后测试
完成以上修改后,运行代码:
- 确保本地服务器正常运行,
index.json可以正常访问 - 查看控制台日志,如果有错误会清晰打印出来
- 视图出现后会自动发起请求,成功后显示对应的产品价格
内容的提问来源于stack exchange,提问作者EdwardKirk
相关产品推荐
相关产品推荐

