将 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 这样的其他格式,你可以实现一个包装器来进行必要的转换。
我正在尝试为包含 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 这样的其他格式,你可以实现一个包装器来进行必要的转换。