I'm trying to implement Codable for a class which contains a NSAttributedString, but I get errors at compile time:
try container.encode(str, forKey: .str)
error ambiguous reference to member 'encode(_:forKey:)'
and
str = try container.decode(NSMutableAttributedString.self, forKey: .str)
error: No 'decode' candidates produce the expected contextual type 'NSAttributedString'
I can get around it by using the NSData from the string, but thought this should work I would have thought
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
doesn’t conform to Codable
, so you can’t do this directly.
If you just want to store the data you can implement a simple wrapper around your attributed string that conforms to Codable and use that in your data class. This is rather easy since you can convert the attributed string to Data
using 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 including HTML, RTF and Microsoft Word.
Resist the temptation to add a Codable conformance to NSAttributedString in an extension. This will cause trouble when Apple adds this conformance or you add another library that does this.
If, on the other hand, you need this to communicate with a server or some other program, you need to exactly match the required data format. If you only need a plain string you probably should not use NSAttributedString at all. If it is some other format like markdown you could implement a wrapper that does the necessary transforms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With