将 Codable 用于 NSAttributedString 时出错

Error using Codable for NSAttributedString

我正在尝试为包含 NSAttributedString 的 class 实现 Codable,但我在编译时遇到错误:

try container.encode(str, forKey: .str)

error ambiguous reference to member 'encode(_:forKey:)'

str = try container.decode(NSMutableAttributedString.self, forKey: .str)

error: No 'decode' candidates produce the expected contextual type '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'
    }
}

如果您只想对文本内容进行解码和编码并将其转换回 from/to NS(Mutual)AttributedString 您可以尝试类似的方法:

class Text : Codable {
var str : NSMutableAttributedString?

enum CodingKeys: String, CodingKey {
    case str
}

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try? container.encode(str?.string, forKey: .str)
}

required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    if let content =  try? container.decode(String.self, forKey: .str){
        str = NSMutableAttributedString(string: content)
        // ADD any attributes here if required...
    }
  }
}

NSAttributedString不符合Codable,所以不能直接这样做。

如果您只想存储数据,您可以围绕符合 Codable 的属性字符串实现一个简单的包装器,并在您的数据中使用它 class。这很容易,因为您可以使用 data(from:documentAttributes) when encoding. When decoding you first read the data and then initialize your attributed string using init(data:options:documentAttributes:). It supports various data formats 将属性字符串转换为 Data,包括 HTML、RTF 和 Microsoft Word。

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

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