如何为不存在的Codable属性通过PropertyWrapper设置默认值
解决方案:让PropertyWrapper处理JSON中缺失的键
问题根源在于当前的DefaultTodayDate仅实现了带Decoder的初始化方法,当JSON中没有date键时,Swift Codable解码器会直接抛出keyNotFound错误,不会触发PropertyWrapper的初始化逻辑。要解决这个问题,只需给PropertyWrapper添加一个无参的默认初始化方法,让解码器在找不到对应键时自动使用默认值。
修改后的PropertyWrapper代码
@propertyWrapper public struct DefaultTodayDate: Codable { public var wrappedValue: Date private let dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.timeZone = TimeZone(secondsFromGMT: 0) formatter.locale = Locale(identifier: "en_US_POSIX") formatter.dateFormat = "y-MM-dd'T'HH:mm:ss" return formatter }() // 新增无参初始化,处理JSON中无对应键的场景 public init() { self.wrappedValue = Date() } public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() do { let stringDate = try container.decode(String.self) self.wrappedValue = dateFormatter.date(from: stringDate) ?? Date() } catch { // 处理null、无效格式等异常,返回当前日期 self.wrappedValue = Date() } } public func encode(to encoder: Encoder) throws { try wrappedValue.encode(to: encoder) } }
模型代码保持不变
struct MyModel: Codable { @DefaultTodayDate var date: Date }
验证效果
当解析不含date的JSON时,解码器会自动调用DefaultTodayDate的无参初始化,将date属性设为当前日期:
let json = #"{ "book": "test" }"#.data(using: .utf8)! let result = try! JSONDecoder().decode(MyModel.self, from: json) print(result.date) // 输出当前日期,符合预期
原有的有效日期字符串、空字符串、null等场景依然正常工作,不会受到影响。
内容的提问来源于stack exchange,提问作者Sajjad
相关产品推荐
相关产品推荐

