SwiftUI 2环境下如何正确解析JSON并将Group数组渲染为列表展示
问题解决指南
1. 现有代码的问题点
- 你将Group和Product两个独立的JSON结构揉在同一个Post模型里,完全不符合JSON的层级关系,会直接导致解析失败
- 你提供的JSON片段存在语法缺失,修正后的完整结构为外层包含
groups和goods两个数组字段 - 编码键枚举里的分组字段写为
group,但实际JSON对应的键是groups,拼写不匹配 - 解析时使用
try!强制解包,一旦字段缺失会直接触发崩溃,不建议在生产代码中使用
2. 正确的Decodable模型定义
// 对应JSON根节点的外层结构 struct ResponseModel: Decodable { let groups: [GroupItem] let goods: [ProductItem] } // groups数组的单个元素结构 struct GroupItem: Decodable { let id: String let name: String let img: String // 如果字段可能缺失可以改为可选类型,比如 let img: String? } // goods数组的单个元素结构 struct ProductItem: Decodable { let id: Int let name: String let text: String let price: Int let unit: String let index: String let img: String let groups: [String] // 对应你需要提取的分组数组 }
3. JSON解析工具方法
func loadLocalJSON() -> ResponseModel? { // 替换成你自己的JSON文件名 guard let fileURL = Bundle.main.url(forResource: "data", withExtension: "json") else { print("未找到目标JSON文件") return nil } do { let jsonData = try Data(contentsOf: fileURL) let decodedResult = try JSONDecoder().decode(ResponseModel.self, from: jsonData) return decodedResult } catch { print("JSON解析失败,错误信息:\(error)") return nil } }
4. SwiftUI 2 列表展示实现
展示顶层groups数组的列表
struct GroupListPage: View { let groupList: [GroupItem] var body: some View { List(groupList, id: \.id) { item in HStack(spacing: 12) { // 如果图片是网络链接,可用AsyncImage加载;本地图片直接用Image加载即可 AsyncImage(url: URL(string: item.img)) { image in image.resizable() } placeholder: { Color.gray.frame(width: 40, height: 40) } .frame(width: 40, height: 40) .cornerRadius(4) Text(item.name) } } .navigationTitle("全部分组") } }
展示单个商品关联的groups数组
struct ProductGroupListPage: View { // 传入商品对应的groups数组 let productGroups: [String] var body: some View { List(productGroups, id: \.self) { groupName in Text(groupName) } .navigationTitle("商品关联分组") } }
页面调用示例
struct MainPage: View { @State private var responseData: ResponseModel? var body: some View { NavigationView { if let data = responseData { // 展示全部分组列表 GroupListPage(groupList: data.groups) // 如果要展示某个商品的分组,替换为 ProductGroupListPage(productGroups: data.goods[0].groups) } else { ProgressView("加载数据中") .onAppear { responseData = loadLocalJSON() } } } } }
内容的提问来源于stack exchange,提问作者Евгений Штин
相关产品推荐
相关产品推荐

