What's new in Foundation

RSS for tag

Discuss the WWDC21 session What's new in Foundation.

Posts under wwdc21-10109 tag

1 Post
Sort by:

Post

Replies

Boosts

Views

Activity

Storing AttributedString
I was playing around a bit with the new AttributedString and a few questions came up. I saw this other forum question "JSON encoding of AttributedString with custom attributes", but I did not completely understand the answer and how I would need to use it. I created my custom attribute where I just want to store additional text like this: enum AdditionalTextAttribute: CodableAttributedStringKey, MarkdownDecodableAttributedStringKey {     typealias Value = AttributedString     static let name = "additionalText" } I then extended the AttributeScopes like this: extension AttributeScopes {     struct MyAppAttributes: AttributeScope {         let additionalText: AdditionalTextAttribute         let swiftUI: SwiftUIAttributes     }     var myApp: MyAppAttributes.Type { MyAppAttributes.self } } and I also implemented the AttributeDynamicLookup like this: extension AttributeDynamicLookup {     subscript<T: AttributedStringKey>(dynamicMember keyPath: KeyPath<AttributeScopes.MyAppAttributes, T>) -> T { self[T.self] } } So next I created my AttributedString and added some attributes to it: var attStr = AttributedString("Hello, here is some text.") let range1 = attStr.range(of: "Hello")! let range2 = attStr.range(of: "text")! attStr[range1].additionalText = AttributedString("Hi") attStr[range2].foregroundColor = .blue attStr[range2].font = .caption2 Next I tried to create some JSON from my string and took a look at it like this: let jsonData = try JSONEncoder().encode(attStr) print(String(data: jsonData, encoding: .utf8) ?? "no data") //print result: ["Hello",{},", here is some ",{},"text",{"SwiftUI.ForegroundColor":{},"SwiftUI.Font":{}},".",{}] I guess it makes sense, that both SwiftUI.ForegroundColor and SwiftUI.Font are empty, because they both do not conform to Codable protocol. My first question would be: Why does my additionalText attribute not show up here? I next tried to extend Color to make it codable like this: extension Color: Codable {     enum CodingKeys: CodingKey {         case red, green, blue, alpha         case desc     }     public func encode(to encoder: Encoder) throws {         var container = encoder.container(keyedBy: CodingKeys.self)         guard let cgColor = self.cgColor,               let components = cgColor.components else {                   if description.isEmpty { throw CodingErrors.encoding }                   try container.encode(description, forKey: .desc)                   return               }         try container.encode(components[0], forKey: .red)         try container.encode(components[1], forKey: .green)         try container.encode(components[2], forKey: .blue)         try container.encode(components[3], forKey: .alpha)     }     public init(from decoder: Decoder) throws {         let container = try decoder.container(keyedBy: CodingKeys.self)         if let description = try container.decodeIfPresent(String.self, forKey: .desc) {             if description == "blue" {                 self = Color.blue                 return             }             throw CodingErrors.decoding         }         let red = try container.decode(CGFloat.self, forKey: .red)         let green = try container.decode(CGFloat.self, forKey: .green)         let blue = try container.decode(CGFloat.self, forKey: .blue)         let alpha = try container.decode(CGFloat.self, forKey: .alpha)         self.init(CGColor(red: red, green: green, blue: blue, alpha: alpha))     } } But it looks like even though Color is now codable, the encoding function does not get called when I try to put my attributed string into the JSONEncoder. So my next question is: Does it just not work? Or do I also miss something here? Coming to my last question: If JSONEncoder does not work, how would I store an AttributedString to disk?
4
0
1.7k
1w