将模型存储在 UserDefault 中时如何处理模型迁移?

Ton*_*Lin 5 nsuserdefaults ios swift

我有一个名为User符合CodableSwift4 中引入的对象。

例如,这个对象曾经是

struct User: Codable {
    var firstName: String
}
Run Code Online (Sandbox Code Playgroud)

我们使用PropertyListDecoder().decode(User.self, from: data)PropertyListEncoder().encode(value)将其编码UserData并解码DataUser

现在我们将对象更新为

struct User: Codable {
    var firstName: String
    var isLoggedIn: Bool
}
Run Code Online (Sandbox Code Playgroud)

如果我们的应用程序从旧应用程序更新,旧应用程序Data存储在UserDefault. 更新后应用程序要做的第一件事就是获取它Data并尝试User使用PropertyListDecoder().decode(User.self, from: data). 但是,它给出了一个错误:

po PropertyListDecoder().decode(User.self, from: data)
? DecodingError
  ? keyNotFound : 2 elements
    - .0 : CodingKeys(stringValue: "isLoggedIn", intValue: nil)
    ? .1 : Context
      - codingPath : 0 elements
      - debugDescription : "No value associated with key CodingKeys(stringValue: \"isLoggedIn\", intValue: nil) (\"isLoggedIn\")."
      - underlyingError : nil
Run Code Online (Sandbox Code Playgroud)

知道在这种情况下我将如何处理模型迁移吗?我知道对于 Coredata,有一些简单的方法可以解决这个问题,但我不知道如何在 UserDefault 中实现它。

ala*_*vaa 6

您可以实现解码初始值设定项并设置默认值(isLoggedIn如果没有):

struct User: Codable {
  var firstName: String
  var isLoggedIn: Bool

  enum Keys: CodingKey {
    case firstName
    case isLoggedIn
  }

  public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    firstName = try container.decode(String.self, forKey: .firstName)
    isLoggedIn = try container.decodeIfPresent(Bool.self, forKey: .isLoggedIn) ?? false
  }
}
Run Code Online (Sandbox Code Playgroud)