I have an object called User that conforms to Codable introduced in Swift4.
for example, this object used to be
struct User: Codable {
var firstName: String
}
and we use PropertyListDecoder().decode(User.self, from: data) and PropertyListEncoder().encode(value) to encode the User into Data and decode Data into User.
Now we updated the object to be
struct User: Codable {
var firstName: String
var isLoggedIn: Bool
}
If our app updated from the old app that has the old Data stored in UserDefault. The first thing app gonna do after update is fetch this Data and tries to decode into User by using PropertyListDecoder().decode(User.self, from: data). But, it gives an error:
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
Any idea how I would handle the model migration in this case? I know that for Coredata there's some easy ways to deal with this but I have no idea how to pull it off in UserDefault.
You could implement the decode initializer and set a default value for isLoggedIn if there isn't any:
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
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With