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

如何让带@Published属性的ObservableObject实现Codable?

为带@Published属性的ObservableObject恢复自动Codable合成能力

问题场景

以下代码可以正常编译:

class Thing: Codable, ObservableObject {
    var feature: String
}

但给feature添加@Published包装后,编译报错:

class Thing: Codable, ObservableObject {
    @Published var feature: String
}

报错信息:

🛑 Class 'Thing' has no initializers
🛑 Type 'Thing' does not conform to protocol 'Decodable'
🛑 Type 'Thing' does not conform to protocol 'Encodable'

根源在于:@Published本身未实现Codable,即便被包装的String符合Codable,Swift也无法自动合成Thing的Codable实现。

尝试直接扩展Published实现Codable的方案也失败了:

extension Published: Codable where Value: Codable {
    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(wrappedValue) // 🛑 'wrappedValue' is unavailable: @Published is only available on properties of classes
    }

    public init(from decoder: Decoder) throws {
        var container = try decoder.singleValueContainer()
        wrappedValue = try container.decode(Value.self) // 🛑 'wrappedValue' is unavailable: @Published is only available on properties of classes
    }
}

错误原因是wrappedValue无法在Published的扩展中直接访问,它仅能在类的实例属性上下文中调用。

便捷解决方案(无需手动实现encode/init方法)

方案1:利用Swift 5.5+的@Codable注解

给@Published属性添加@Codable注解,明确告知编译器在合成Codable逻辑时,直接处理包装后的底层值:

class Thing: Codable, ObservableObject {
    @Codable
    @Published var feature: String
}

该注解会让编译器跳过Published包装层,直接对wrappedValue执行编码解码操作,自动生成符合要求的Codable实现。

方案2:扩展编码/解码容器支持Published

全局添加以下两个扩展,让KeyedEncodingContainer和KeyedDecodingContainer能处理Published类型的属性:

extension KeyedEncodingContainer {
    mutating func encode<T: Codable>(_ value: Published<T>, forKey key: Key) throws {
        try encode(value.wrappedValue, forKey: key)
    }
}

extension KeyedDecodingContainer {
    func decode<T: Codable>(_ type: Published<T>.Type, forKey key: Key) throws -> Published<T> {
        let wrappedValue = try decode(T.self, forKey: key)
        return Published(wrappedValue: wrappedValue)
    }
}

添加扩展后,原有的Thing类即可正常编译,Swift会自动合成完整的Codable实现,无需修改类内部代码。这个方案适合多个类需要同时支持@Published和Codable的场景。

内容的提问来源于stack exchange,提问作者Hugo Timothy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:01:22