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

为包含NSAttributedString的类实现Codable时遇编译错误

嘿,我来帮你搞定这个NSAttributedString实现Codable的问题~

首先咱们先拆解下你遇到的两个错误:

  1. 编码时的歧义错误:Swift的encode(_:forKey:)没有直接支持NSAttributedString的重载,因为NSAttributedString本身并没有实现Codable协议,编译器不知道该用哪个编码逻辑,所以抛出了歧义错误。
  2. 解码时的类型不匹配错误:你尝试解码成NSMutableAttributedString,但你的属性str是NSAttributedString类型,而且本质上这两个类都没实现Codable,所以没有对应的decode方法能返回你需要的类型。

其实你不用绕弯子转NSData,直接给NSAttributedString扩展Codable协议就行——利用它本身支持的NSCoding能力,通过归档/解归档来实现Codable的编码解码逻辑。

下面是完整的解决方案:

第一步:给NSAttributedString扩展Codable

extension NSAttributedString: Codable {
    public func encode(to encoder: Encoder) throws {
        // 把NSAttributedString归档成Data
        let data = try NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false)
        var container = encoder.singleValueContainer()
        try container.encode(data)
    }
    
    public init(from decoder: Decoder) throws {
        // 解码出Data,再解归档成NSAttributedString
        let container = try decoder.singleValueContainer()
        let data = try container.decode(Data.self)
        guard let attributedString = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSAttributedString.self, from: data) else {
            throw DecodingError.dataCorruptedError(in: container, debugDescription: "无法解归档得到NSAttributedString")
        }
        self.init(attributedString: attributedString)
    }
}

第二步:修改你的Text类

现在NSAttributedString已经支持Codable了,你的Text类可以直接使用自动合成的Codable实现,当然如果你需要自定义编码解码逻辑,保留原来的代码也完全没问题,现在不会再报错了:

class Text: Codable {
    var str: NSAttributedString

    enum CodingKeys: String, CodingKey {
        case str
    }

    // 可选:如果不需要自定义逻辑,这两个方法可以完全删掉,Codable会自动合成
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(str, forKey: .str) // 现在不会有歧义了
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        str = try container.decode(NSAttributedString.self, forKey: .str) // 类型匹配,解码正常
    }
}

额外说明

如果你需要使用NSMutableAttributedString,可以在扩展时给它也加Codable支持,或者在解码后把NSAttributedString转成可变版本:

// 解码后转可变
let mutableStr = NSMutableAttributedString(attributedString: str)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:10:34