You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将[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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 18:45:03