将变量添加到已保存的用户默认值变量 创建一个 protected 变量:

问题描述

我下载了一个快速文件,应该可以帮助我保存和加载自定义变量:

import Foundation

protocol ObjectSavable {
func setToObject<Object>(_ object: Object,forKey: String) throws where Object: Encodable
func getToObject<Object>(forKey: String,castTo type: Object.Type) throws -> Object where Object: Decodable
}

extension UserDefaults: ObjectSavable {
func setToObject<Object>(_ object: Object,forKey: String) throws where Object: Encodable {
    let encoder = JSONEncoder()
    do {
        let data = try encoder.encode(object)
        set(data,forKey: forKey)
    } catch {
        throw ObjectSavableError.unableToEncode
    }
}

func getToObject<Object>(forKey: String,castTo type: Object.Type) throws -> Object where Object: Decodable {
    guard let data = data(forKey: forKey) else { throw ObjectSavableError.noValue }
    let decoder = JSONDecoder()
    do {
        let object = try decoder.decode(type,from: data)
        return object
    } catch {
        throw ObjectSavableError.unableToDecode
    }
}
}

enum ObjectSavableError: String,LocalizedError {
case unableToEncode = "Unable to encode object into data"
case noValue = "No data object found for the given key"
case unableToDecode = "Unable to decode object into given type"
}

我有这个Person结构:

struct Person: Encodable,Decodable {
    var firstName: String
    var lastName: String
    var birthday: Date

    init() {
        self.firstName = "Tim"
        self.lastName = "Cook"
        self.birthday = Date()
    }
}

我也有这段代码用于保存/加载Person结构(正在使用上面的代码)

保存:

print("Saving object...")
    let person: Person = Person()
    
    do {
        try UserDefaults.standard.setToObject(person,forKey: "person")
        print("Object saved successfully")
    } catch let err {
        print("Error while saving object:\n\(err.localizedDescription)")
    }

正在加载:

print("Loading object...")
    
    do {
        self.person = try UserDefaults.standard.getToObject(forKey: "person",castTo: Person.self)
        print("Successfully load object:\n\(self.person!)")
    } catch let err {
        print("Error while loading object:\n\(err.localizedDescription)")
    }

现在,所有这些都有效。 但是,假设我以这种方式发布了我的应用,然后我想向Person添加一个新变量,例如,我将添加一个favorite

struct Person: Encodable,Decodable {
    var firstName: String
    var lastName: String
    var birthday: Date
    var favorite: Bool = false

    init() {
        self.firstName = "Tim"
        self.lastName = "Cook"
        self.birthday = Date()
    }
}

在更新之前,应用程序(在favorite中没有Person变量)将被保存,而没有favorite变量。更新之后,应用程序将尝试使用Person变量加载先前保存的favorite。这就是失败的原因,因为较旧版本的数据中没有favorite变量。因此会引发错误。

我的问题是,有没有办法在从用户默认值中解码Person时,如果找不到任何匹配的变量(例如:favorite),而不是抛出错误,它将尝试自动创建吗? (来自var favorite = false )?

我的项目:https://github.com/orihpt/Encodable

谢谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)