我正在尝试为包含 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'
}
}
NSAttributedString
与 Codable
不符,所以你不能直接这样做。
如果您只想存储数据,您可以在符合 Codable 的属性字符串周围实现一个简单的包装器,并在数据类中使用它。这相当容易,因为您可以在编码时使用
Data
将属性字符串转换为
data(from:documentAttributes)
。解码时,您首先读取数据,然后使用 init(data:options:documentAttributes:)
初始化属性字符串。它支持各种数据格式,包括 HTML、RTF 和 Microsoft Word。
抵制在扩展中向 NSAttributedString 添加 Codable 一致性的诱惑。当 Apple 添加此一致性或您添加另一个执行此操作的库时,这会引起麻烦。
另一方面,如果您需要它与服务器或其他程序进行通信,则需要完全匹配所需的数据格式。如果您只需要一个纯字符串,您可能根本不应该使用 NSAttributedString。如果是其他格式(例如 markdown),您可以实现一个包装器来执行必要的转换。
尝试使用 AttributedString 而不是 NSAttributedString
如果您只想对文本内容进行解码和编码并将其转换回
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...
}
}
}