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

UserDefaults解码失败:仅支持适配NSSecureCoding的类

问题解决方法

原因分析

你使用的NSKeyedUnarchiver.unarchivedObject(ofClass:from:)是苹果推出的安全解码API,它强制要求解码的类必须遵循NSSecureCoding协议。但你的PlayerClass仅实现了旧的NSCoding协议,且保存数据时开启了requiringSecureCoding: false生成非安全编码数据,因此解码时触发报错。


方案一:兼容旧编码(快速临时解决)

直接替换解码代码为旧的非安全解码方法,同时做好类型转换:

if let dataToRetrieve = UserDefaults.standard.data(forKey: "currentPlayerToon") {
    do {
        guard let returnedPlayerInformation = NSKeyedUnarchiver.unarchiveObject(with: dataToRetrieve) as? PlayerClass else {
            print("类型转换失败")
            return
        }
        print("Success")
    } catch {
        print(error)
    }
}

⚠️ 注意:苹果不推荐这种方式,存在安全风险,仅作为临时兼容方案。


方案二:升级为安全编码(官方推荐)

从编码到解码全程遵循苹果安全规范,这是长期维护的最优解:

1. 修改类声明,遵循NSSecureCoding

补充实现supportsSecureCoding静态属性,并重写编码解码方法:

class PlayerClass: NSObject, NSSecureCoding {
    static var supportsSecureCoding: Bool {
        return true
    }
    
    var toonName: String
    
    // 自定义初始化方法
    init(toonName: String) {
        self.toonName = toonName
        super.init()
    }
    
    // 解码方法(NSSecureCoding要求)
    required init?(coder: NSCoder) {
        guard let toonName = coder.decodeObject(forKey: "toonName") as? String else {
            return nil
        }
        self.toonName = toonName
        super.init()
    }
    
    // 编码方法(NSSecureCoding要求)
    func encode(with coder: NSCoder) {
        coder.encode(toonName, forKey: "toonName")
    }
}

2. 修改保存代码,启用安全编码

将requiringSecureCoding参数改为true:

do {
    let dataToSave = try NSKeyedArchiver.archivedData(withRootObject: cachedToonToSave, requiringSecureCoding: true)
    UserDefaults.standard.set(dataToSave, forKey: "currentPlayerToon")
    print("saving worked")
} catch {
    print("saving failed")
}

3. 解码代码保持不变

此时原有的安全解码方法可正常执行:

if let dataToRetrieve = UserDefaults.standard.data(forKey: "currentPlayerToon") {
    do {
        let returnedPlayerInformation = try NSKeyedUnarchiver.unarchivedObject(ofClass: PlayerClass.self, from: dataToRetrieve)
        print("Success")
    } catch {
        print(error)
    }
}

内容的提问来源于stack exchange,提问作者Mason Ballowe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 20:15:29