Codable API 能否用于解码使用 NSKeyedArchiver.archivedData 编码的数据?

Can Codable APIs be used to decode data encoded with NSKeyedArchiver.archivedData?

我正在将代码库从使用 NSCoding 转换为使用 Codable。在尝试恢复使用 NSCoding 编码的数据时,我遇到了 运行 问题。我有一个用代码编码的对象:

let encodedUser = NSKeyedArchiver.archivedData(withRootObject: user)
let userDefaults = UserDefaults.standard
userDefaults.set(encodedUser, forKey: userKey)
userDefaults.synchronize()

之前用代码解码:

if let encodedUser = UserDefaults.standard.data(forKey: userKey) {
  if let user = NSKeyedUnarchiver.unarchiveObject(with: encodedUser) as? User {
    \ do stuff
  }
}

User 对象更新为 Codable 后,我尝试更新 archive/unarchive 代码以使用 PropertyListDecoder,因为我看到 archivedData(withRootObject:) returns 数据格式为 NSPropertyListBinaryFormat_v1_0。 运行宁此代码时:

if let encodedUser = UserDefaults.standard.data(forKey: userKey) {
  let user = try! PropertyListDecoder().decode(User.self, from: encodedUser)
  \ do stuff
}

我在查找第一个密钥时遇到 keyNotFound 错误,并且在我的 init(from: Decoder) 中设置了断点,我可以看到容器没有密钥。我还尝试使用 PropertyListSerialization.propertyList(from:options:format) 来查看是否可以将该结果传递给 PropertyListDecoder,但该函数给了我一个 NSCFDictionary,它的结构非常奇怪,但似乎确实包含我正在寻找的所有数据。

那么,如果一个对象是用 NSKeyedArchiver.archivedData(withRootObject:) 编码的,那么是否可以使用 Codable API 对其进行解码?我怎样才能做到这一点?

我认为答案几乎肯定是否定的,您不能使用 Codable 来解码 NSCoding 编码的内容。我想摆脱代码库中的所有 NSCoding 垃圾,并确定了一条迁移路径,在该路径上,我在关键数据模型中实现了两种协议,以将存储的数据从 NSCoding 转换为 Codable 格式,将来当我有足够多的用户更新时,我将删除 NSCoding。