对 NSAttributedString 使用 Codable 时出错

问题描述 投票:0回答:3

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

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

对成员“encode(_:forKey:)”的错误引用不明确

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

错误:没有“解码”候选者产生预期的上下文类型“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'
    }
}
swift nsattributedstring codable
3个回答
6
投票

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

如果您只想存储数据,您可以在符合 Codable 的属性字符串周围实现一个简单的包装器,并在数据类中使用它。这相当容易,因为您可以在编码时使用

Data
 将属性字符串转换为 
data(from:documentAttributes)
。解码时,您首先读取数据,然后使用
init(data:options:documentAttributes:)
初始化属性字符串。它支持各种数据格式,包括 HTML、RTF 和 Microsoft Word。

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

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


0
投票

尝试使用 AttributedString 而不是 NSAttributedString


-1
投票

如果您只想对文本内容进行解码和编码并将其转换回

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...
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.