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

Swift中NSKeyedUnarchiver在字符串转数据后解归档失败问题排查

问题原因与解决方案

这个问题的核心在于直接用UTF-8编码把二进制归档数据转成String是完全不可行的,具体原因如下:

  • NSKeyedArchiver生成的Data是纯二进制格式,里面包含大量不符合UTF-8编码规范的字节序列。UTF-8是用来表示文本字符的编码,它对字节序列有严格的规则,当遇到非法字节时,Swift的String(decoding:as:)会自动把这些非法字节替换成Unicode的替换字符(�)——这一步已经不可逆地损坏了原始的归档数据。
  • 当你再用stringData.data(using: .utf8)把字符串转回Data时,那些被替换的字节已经无法恢复成原来的二进制内容,自然无法被NSKeyedUnarchiver正确解析。

正确的解决方式:使用Base64编码

Base64是专门设计用来将二进制数据转换为可安全存储/传输的字符串的编码方式,它会把所有二进制字节映射到64个可打印的ASCII字符,完全不会丢失或修改原始数据。

修正后的代码如下:

do {
    // 归档为Data,再转成Base64字符串
    let data = try NSKeyedArchiver.archivedData(withRootObject: drawItems, requiringSecureCoding: false)
    let base64String = data.base64EncodedString()
    print("HERE successfully converted to a Base64 string: ", base64String)
    
    // 将Base64字符串转回Data,再解归档
    if let restoredData = Data(base64Encoded: base64String), 
       let allItems = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(restoredData) as? [DrawItem] {
        print("HERE items: ", allItems)
    } else {
        print("HERE FAILED to unarchive")
    }
} catch {
    print("Failed: ", error)
}

这样处理后,二进制数据就能在Data和String之间无损转换,后端存储Base64字符串也完全没有问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:44:10