如何创建适配指定Swift Struct的JSON及JSONDecoder
适配Example结构体的JSON数据与JSONDecoder解析方案
一、对应的JSON数据示例
下面是完全适配你给出的Example结构体的JSON数据示例,嵌套的rows字段对应结构体里的[ProductRow]数组,所有字段名和结构体属性名严格匹配(默认Codable按属性名匹配JSON键):
{ "id": 1, "title": "智能手表", "category": "穿戴设备", "year": "2024", "imageName": "watch_main", "bannerName": "watch_banner", "URLScheme": "myapp://device/watch/1", "isFavorite": true, "rows": [ { "title": "续航时长", "value": "14天" }, { "title": "防水等级", "value": "IP68" }, { "title": "售价", "value": "1299元" } ] }
如果是多个Example对象的集合,JSON格式如下:
[ { "id": 1, "title": "智能手表", // 其他字段... "rows": [...] }, { "id": 2, "title": "无线耳机", // 其他字段... "rows": [...] } ]
二、JSONDecoder解析实现
1. 从JSON字符串解析
因为你的结构体已经遵循Codable协议,直接用Swift原生JSONDecoder即可完成解析,无需额外编写解码逻辑:
// 示例JSON字符串 let jsonString = """ { "id": 1, "title": "智能手表", "category": "穿戴设备", "year": "2024", "imageName": "watch_main", "bannerName": "watch_banner", "URLScheme": "myapp://device/watch/1", "isFavorite": true, "rows": [ { "title": "续航时长", "value": "14天" } ] } """ // 字符串转Data guard let jsonData = jsonString.data(using: .utf8) else { fatalError("无法将JSON字符串转为Data") } // 解析为Example对象 do { let example = try JSONDecoder().decode(Example.self, from: jsonData) print("解析成功:\(example.title)") } catch { print("解析失败:\(error.localizedDescription)") }
2. 从本地JSON文件解析
如果JSON数据保存在项目本地文件中(比如products.json),可以这样读取并解析:
guard let fileUrl = Bundle.main.url(forResource: "products", withExtension: "json") else { fatalError("找不到目标JSON文件") } do { let jsonData = try Data(contentsOf: fileUrl) // 解析单个对象 let singleExample = try JSONDecoder().decode(Example.self, from: jsonData) // 如果是对象数组,就解析为[Example].self // let exampleList = try JSONDecoder().decode([Example].self, from: jsonData) } catch { print("文件读取或解析失败:\(error)") }
3. 常见适配调整
如果JSON里的键名和结构体属性名不一致(比如JSON用urlScheme而不是URLScheme),可以通过添加CodingKeys枚举做映射:
struct Example: Hashable, Codable, Identifiable { // 原有属性... enum CodingKeys: String, CodingKey { case id, title, category, year, imageName, bannerName case URLScheme = "urlScheme" // 映射JSON的urlScheme到结构体的URLScheme case isFavorite, rows } }
内容的提问来源于stack exchange,提问作者Drake Jordan
相关产品推荐
相关产品推荐

