微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何防止在 api 更改时解码/编码时丢失密钥?

如何解决如何防止在 api 更改时解码/编码时丢失密钥?

以下情况: 我使用了几个使用数据结构的设备。如果我现在为较新版本扩展结构的键,则对新结构进行编码然后进行同步。作为同步的结果,旧数据结构用于解码。当您随后与新设备同步时,新密钥已丢失。我怎样才能防止这种情况?

enter image description here

使用游乐场

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 包裹你的最后一条 decode 语句,你会发现发生了什么

  do {
   newDevice = try JSONDecoder().decode(NewApi.self,from: newData)
} catch {
   print(error)
}

错误将是这样的 keyNotFound(CodingKeys(stringValue: "value",intValue: nil),Swift.DecodingError.Context(codingPath: [],debugDescription: "No value associated with key CodingKeys(stringValue: "value",intValue: nil) ("value" )”,底层错误: 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”属性提供默认值(如果未找到)

我建议您将此说服 init 移至“NewApi”结构的扩展,以免丢失默认初始化程序。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。