对NSAttributedString使用Codable时出错

dav*_*n11 4 nsattributedstring swift codable

我正在尝试为包含NSAttributedString的类实现Codable,但是在编译时出现错误:

try container.encode(str, forKey: .str)
Run Code Online (Sandbox Code Playgroud)

对成员'encode(_:forKey :)的错误含糊的引用

和

str = try container.decode(NSMutableAttributedString.self, forKey: .str)
Run Code Online (Sandbox Code Playgroud)

错误:没有任何“解码”候选者产生预期的上下文类型“ NSAttributedString”

我可以通过使用字符串中的NSData来解决它,但是我认为这应该可以工作

class Text : Codable {
    var str : NSAttributedString

    enum CodingKeys: String, CodingKey {
        case str
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(str, forKey: .str). <-- error ambiguous reference to member 'encode(_:forKey:)'
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        str = try container.decode(NSMutableAttributedString.self, forKey: .str)  <-- error: No 'decode' candidates produce the expected contextual type 'NSAttributedString'
    }
}
Run Code Online (Sandbox Code Playgroud)

Sve*_*ven 5

NSAttributedString不符合Codable,因此您不能直接执行此操作。

如果只想存储数据,则可以在符合Codable的属性字符串周围实现一个简单的包装程序,并在数据类中使用它。这是相当容易的,因为你可以在属性串转换为Data使用data(from:documentAttributes)编码时。解码时,首先读取数据,然后使用初始化属性字符串init(data:options:documentAttributes:)。它支持各种数据格式,包括HTML,RTF和Microsoft Word。

抵制为扩展中的NSAttributedString添加Codable一致性的诱惑。当Apple添加此一致性或您添加另一个执行此操作的库时,这将引起麻烦。

另一方面,如果您需要它与服务器或其他程序通信,则需要完全匹配所需的数据格式。如果只需要一个纯字符串,则可能根本不应该使用NSAttributedString。如果它是诸如markdown之类的其他格式,则可以实现一个包装器,该包装器进行必要的转换。