如何将[String: NSAttributedString]字典存入SwiftData并解决解码问题?
方案1:通过NSKeyedArchiver/Unarchiver序列化Data
你的原代码存在两个核心问题:一是JSONSerialization无法直接处理NSAttributedString(它不属于JSON原生支持的类型),二是NSAttributedString未实现Codable协议,导致JSONDecoder报错。正确的做法是利用NSAttributedString自带的NSSecureCoding支持,通过归档方式完成序列化:
编码示例
let dictionary: [String: NSAttributedString] = ["First Key": NSAttributedString(string: "First Value")] do { let data = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: true) // 将data存入SwiftData } catch { print(error) }
解码示例
do { guard let decodedDict = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [String: NSAttributedString] else { // 处理类型不匹配或解码失败的情况 return } // 使用解码后的字典 } catch { print(error) }
方案2:SwiftData @Transformable 属性(更便捷)
SwiftData支持@Transformable属性,能自动处理自定义类型的序列化/反序列化,无需手动管理Data。具体步骤如下:
1. 实现ValueTransformer
class AttributedStringDictTransformer: ValueTransformer { override class func transformedValueClass() -> AnyClass { Data.self } override class func allowsReverseTransformation() -> Bool { true } override func transformedValue(_ value: Any?) -> Any? { guard let dict = value as? [String: NSAttributedString] else { return nil } return try? NSKeyedArchiver.archivedData(withRootObject: dict, requiringSecureCoding: true) } override func reverseTransformedValue(_ value: Any?) -> Any? { guard let data = value as? Data else { return nil } return try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [String: NSAttributedString] } } // 注册Transformer,方便后续引用 extension ValueTransformer { static let attributedStringDict = AttributedStringDictTransformer() }
2. 在SwiftData模型中使用
import SwiftData @Model class YourModel { @Attribute(.transformable(by: \.attributedStringDict)) var attributedDict: [String: NSAttributedString] init(attributedDict: [String: NSAttributedString]) { self.attributedDict = attributedDict } }
这样你可以直接操作attributedDict属性,SwiftData会自动完成序列化和反序列化,无需手动处理Data转换。
原代码问题说明
JSONSerialization仅支持JSON原生类型(字符串、数字、数组、字典、null),NSAttributedString不在此列,编码阶段实际会抛出错误。JSONDecoder要求解码类型必须遵守Decodable协议,但NSAttributedString未实现该协议,因此出现你看到的报错。
内容的提问来源于stack exchange,提问作者alionthego
相关产品推荐
相关产品推荐

