You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为不存在的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:55:30