【问题标题】:How to prevent lose keys on decode / encode on api change?如何防止在 api 更改时解码/编码丢失密钥?
【发布时间】:2021-06-04 21:34:57
【问题描述】:

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

使用游乐场

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)

【问题讨论】:

  • 这是一个很好的问题 -- 但是,请发布代码,而不是代码图片,这些图片不可搜索、不可复制/粘贴,并且不适用于移动设备或屏幕阅读器。
  • 当然会丢失,因为旧 API 不知道新密钥。您可以将新键声明为可选。我完全同意 jnpdx。
  • @jnpdx 代码已添加。
  • 不幸的是,可选键不是解决方案。我想避免丢失信息。 @vadian
  • 如果您使用旧 API 对数据进行编码,那么这是不可能的,旧 API 只是删除了 new 键。

标签: swift encoding decode encode decoding


【解决方案1】:

用 do catch 包裹你的最后一个解码语句,你会发现发生了什么

  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" ).",基础错误:无))

您可以做的一件事是创建一个自定义解码器初始化程序

 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”属性,则为其提供默认值

我建议你将这个 convince init 移到“NewApi”结构的扩展中,以免丢失默认初始化程序。

【讨论】:

  • 问题不是上面的代码崩溃了,而是数据丢失了。如果我在我的应用程序中创建用户输入的新值,它会在与旧设备同步时被删除。所以问题是,我怎样才能与旧设备同步而不会丢失带有值的新键。
猜你喜欢
  • 2021-10-20
  • 2016-01-03
  • 2021-08-31
  • 2020-12-18
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多