I am trying to encode an AttributedString to JSON and then decode it back to an AttributedString. But when the AttributedString both (1) contains emoji, and (2) has any attributes assigned, the decoding seems to fail, producing a truncated AttributedString. By dump
-ing the decoded value, I can see that the full string is still in there (in the guts
property) but it is missing in normal uses of the AttributedString.
Below is an example that reproduces the problem.
import Foundation
// An arbitrary AttributedString with emoji
var attrString = AttributedString("12345💕☺️💕☺️💕☺️12345")
// Set an attribute (doesn't seem to matter which one)
attrString.imageURL = URL(string: "http://www.dummy.com/dummy.jpg")!
// Encode the AttributedString
var encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(attrString)
// Print the encoded JSON
print("encoded JSON for AttributedString:")
print(String(data: data, encoding: .utf8)!)
// Output from above omitted, but it looks correct with the full string represented
// Decode the AttributedString and print it
let decoder = JSONDecoder()
let decodedAttrString = try! decoder.decode(AttributedString.self, from: data)
print("decoded AttributedString:")
print(decodedAttrString)
// Output from above is a truncated AttributedString:
//
// 12345💕☺️ {
// NSImageURL = http://www.dummy.com/dummy.jpg
// }
print("dump of AttributedString:")
dump(decodedAttrString)
// Interestingly, `dump` shows that the full string is still in there:
//
// ▿ 12345💕☺️ {
// NSImageURL = http://www.dummy.com/dummy.jpg
// }
// ▿ _guts: Foundation.AttributedString.Guts #0
// - string: "12345💕☺️💕☺️💕☺️12345"
// ▿ runs: 1 element
// ...
//