Swift 如何防止api更改时解码/编码时丢失密钥?
以下情况: 我使用了几个使用数据结构的设备。如果我现在展开新版本结构的键,新结构将被编码,然后同步。作为同步的结果,旧数据结构用于解码。然后与新设备同步时,新密钥已丢失。我怎样才能防止这种情况 使用操场Swift 如何防止api更改时解码/编码时丢失密钥?,swift,encoding,decode,encode,decoding,Swift,Encoding,Decode,Encode,Decoding,以下情况: 我使用了几个使用数据结构的设备。如果我现在展开新版本结构的键,新结构将被编码,然后同步。作为同步的结果,旧数据结构用于解码。然后与新设备同步时,新密钥已丢失。我怎样才能防止这种情况 使用操场 import Foundation struct OLD_API: Codable { var text: String } struct NEW_API: Codable { var text: String let value: Int } // Init data on
import Foundation
struct OLD_API: Codable {
var text: String
}
struct NEW_API: Codable {
var text: String
let value: Int
}
// Init data on device with NEW data struct
var newDevice = NEW_API(text: "Dog", value: 200)
let data = try! JSONEncoder().encode(newDevice)
// .. sync to other devices (new to old)
// modified data on device with OLD data struct
var oldDevice = try! JSONDecoder().decode(OLD_API.self, from: data)
oldDevice.text = "Cat"
let newData = try! JSONEncoder().encode(oldDevice)
// .. sync to other devices (old to new)
// decode data on device with NEW data struct
newDevice = try! JSONDecoder().decode(NEW_API.self, from: newData)
print(newDevice)
用do catch包装您的最后一条解码语句,您将发现发生了什么
do {
newDevice = try JSONDecoder().decode(NewApi.self, from: newData)
} catch {
print(error)
}
错误是这样的
keyNotFound(编码键(stringValue:“值”,intValue:nil),Swift.DecodingError.Context(编码路径:[],调试说明:“没有与键编码键关联的值(stringValue:“值”,intValue:nil)(“值”),UnderlineingError:nil))
您可以做的一件事是创建自定义解码器初始值设定项
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
text = try container.decode(String.self, forKey: .text)
value = (try? container.decode(Int.self, forKey: .value) ) ?? 0
}
如果找不到“value”属性,则为其提供默认值
我建议您将此Converse init移到“NewApi”结构的扩展中,以避免丢失默认初始值设定项。这是一个好问题--但是,请发布代码,而不是代码图片,因为它们不可搜索,不可复制/复制,在移动设备或屏幕阅读器上也不能很好地工作。当然,它们会丢失,因为旧的API不知道新的密钥。您可以将新密钥声明为可选的。我完全同意jnpdx。@添加了jnpdx代码。不幸的是,可选密钥不是解决方案。我想避免丢失信息@Vadian如果使用旧API对数据进行编码,而旧API只是删除了新的密钥,这是不可能的。问题不是上面的代码崩溃了,而是数据丢失了。如果我在我的应用程序中创建了一个新值(用户输入),则在与旧设备同步时,该值将被删除。所以问题是,我怎样才能与旧设备同步,而不丢失带值的新密钥。