ios - 更新已保存的 Codable 结构以添加新属性

标签 ios swift struct properties userdefaults

我的应用程序使用像这样的可编码结构:

public struct UserProfile: Codable {

     var name: String = ""
     var completedGame: Bool = false

     var levelScores: [LevelScore] = []
}

JSONEncoder() 已用于将编码的 UserProfile 数组保存为用户默认值。

在即将到来的更新中,我想向此 UserProfile 结构添加一个新属性。这在某种程度上可能吗?

或者我是否需要创建一个具有相同属性和一个新属性的新 Codable 结构,然后将所有值复制到新结构,然后开始使用该新结构代替 的任何地方以前使用过 UserProfile 结构?

如果我只是向该结构添加一个新属性,那么我将无法加载以前编码的 UserProfile 数组,因为该结构将不再具有匹配的属性。当我找到用于加载已保存用户的代码时:

if let savedUsers = UserDefaults.standard.object(forKey: "SavedUsers") as? Data {
       let decoder = JSONDecoder()
       if let loadedUsers = try? decoder.decode([UserProfile].self, from: savedUsers) {
如果 UserProfile 在编码和保存时所具有的属性不包含 UserProfile 的所有当前属性,则

loadedUsers 不会解码> 结构。

对于更新保存的结构属性有什么建议吗?还是我必须走很远的路重新创建,因为我之前没有提前计划要包含此属性?

感谢您的帮助!

最佳答案

如评论中所述,您可以将新属性设为可选,然后解码将适用于旧数据。

var newProperty: Int?

另一种选择是在解码期间应用默认值,如果该属性丢失。

这可以通过在你的结构中实现 init(from:) 来完成

public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    name = try container.decode(String.self, forKey: .name)
    completedGame = try container.decode(Bool.self, forKey: .completedGame)
    do {
        newProperty = try container.decode(Int.self, forKey: .newProperty)
    } catch {
        newProperty = -1
    }
    levelScores = try container.decode([LevelScore].self, forKey: .levelScores)
}

这需要你定义一个CodingKey枚举

enum CodingKeys: String, CodingKey {
    case name, completedGame, newProperty, levelScores
}

如果您不希望它在代码中使用时是可选的,第三个选项是将其包装在计算的非可选属性中,再次使用默认值。这里 _newProperty 将在存储的 json 中使用,但 newProperty 在代码中使用

private var _newProperty: Int?
var newProperty: Int {
    get {
        _newProperty ?? -1
    }
    set {
        _newProperty = newValue
    }
}

关于ios - 更新已保存的 Codable 结构以添加新属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59558400/

相关文章:

ios - 在 UITableViewCell 中重新加载 collectionview 时应用程序崩溃

ios - 收到通知后我想更改我的 uiwebview

ios - 快速回调不打印

C-错误 : storage size of ‘a’ isn’t known

c - 结构中的函数

ios - UITableViewCell : Dynamic Cell Height by 'Cell Identifier'

ios - 如何使用 Swift 2 在 View Controller 内播放视频 - 'If let' 错误

ios - 单元测试下 UINavigationItem 意外为零

ios - 我只能通过prepareforSegue将新单元添加到 Collection View Controller

c++ - 为什么我的 vector 不能访问嵌套结构中的变量?