构建Airtable API返回JSON的Swift Codable模型时fields部分卡壳求助
解决Airtable API返回数据的Swift Codable模型编写问题
首先纠正你当前Record结构体的id问题:你用UUID()作为默认id,但Airtable API返回的id是字符串类型(如"recBOdydIpM2P3xkZ"),且Identifiable协议的id支持任意Hashable类型,所以需要把id改成String类型并移除默认值,让它从JSON中解码。
接下来处理fields部分:需要创建独立的Fields结构体对应JSON中的fields对象,由于JSON键包含空格、特殊字符(如% GP)不符合Swift命名规范,需通过CodingKeys枚举做键名映射。
完整模型代码
import Foundation struct Record: Codable, Identifiable { let id: String // 对应API返回的字符串id let createdTime: Date let fields: Fields } struct Fields: Codable { let gpPercentage: String let totalRx: Int let grossProfit: Double let totalReceived: Double let date: String // 若需转为Date类型,可自定义解码逻辑 let copay: Double let acquisitionCost: Double let averageGP: Double let tpRemitted: Double // 映射JSON中的特殊键名到Swift规范命名 enum CodingKeys: String, CodingKey { case gpPercentage = "% GP" case totalRx = "Total Rx" case grossProfit = "Gross Profit" case totalReceived = "Total Received" case date = "Date" case copay = "Copay" case acquisitionCost = "Acquisition Cost" case averageGP = "Average GP" case tpRemitted = "TP Remitted" } }
解码注意事项
解码时需配置JSONDecoder的日期策略,适配createdTime的ISO 8601格式:
let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 // 假设data为API返回的Data对象 do { let record = try decoder.decode(Record.self, from: data) print(record) } catch { print("解码失败:\(error)") }
如果需要把fields.date也转为Date类型,可修改Fields中date的类型为Date,并给JSONDecoder添加多格式日期解析逻辑:
// 修改Fields中的date类型 let date: Date // 配置支持两种日期格式的解码器 decoder.dateDecodingStrategy = .custom { decoder in let container = try decoder.singleValueContainer() let dateString = try container.decode(String.self) // 先解析createdTime的ISO8601格式 if let date = ISO8601DateFormatter().date(from: dateString) { return date } // 再解析fields.date的yyyy-MM-dd格式 let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd" formatter.timeZone = TimeZone(secondsFromGMT: 0) guard let date = formatter.date(from: dateString) else { throw DecodingError.dataCorruptedError(in: container, debugDescription: "无法解析日期字符串:\(dateString)") } return date }
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

