问题描述
我想知道在Swift中存储用户设置的最佳方法是什么。对于用户设置,我的意思是简单(小)数据,而不是一些大文件。到目前为止,我使用了一个具有所有要保存的属性的类。
所有这些属性均符合Codable。但是,我没有将整个类保存在UserDefaults中,而是分别保存了每个属性。但是我不喜欢这种方法。它有几个问题:代码变得更长,因为对于每个变量,我必须编写didSet {...}。例如:
var percentage: Double = UserDefaults.standard.double(forKey: "percentage") {
didSet {
UserDefaults.standard.set(percentage,forKey: "percentage")
}
}
如您所见,变量名在此处被写入4次。因此,拼写错误/复制和粘贴错误的可能性很高。
那我为什么不保存整个课程呢?好吧,我注意到,如果我向类添加变量,则即使我为新变量赋予默认值,该类的解码也不再起作用,并且所有数据都会丢失。
似乎有一种解决方法:手动解码。例如:
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(UUID.self,forKey: .id)
name = try container.decode(String.self,forKey: .name)
//etc...
}
但是,手动解码似乎需要我分别解码每个变量。我也不喜欢这样,因为也有很大的机会忘记一个变量等(因此与上面的问题相同)。
我也想做的是为用户提供导出和导入设置以及使用iCloud进行设置同步的选项。对于前者,最好存储整个Settings类(我可以导出和导入JSON文件)。
感谢您的帮助!
解决方法
您可能还需要某种类来管理用户的所有内容,诸如此类:
class SettingsManager {
private let defaults = UserDefaults.standard
var percentage: Double {
get { return defaults.value(forKey: "percentage") as? Double ?? 0.0 }
set { defaults.set(newValue,forKey: "percentage") }
}
}
这样,您可以减少所需的代码量:
// Retrieve a value
let percentage = SettingsManager().percentage
// Set new value
SettingsManager().percentage = 0.55
理想情况下,您可能会使用here之类的属性包装器。 这样就无需对值进行编码/解码,直到它成为自定义类型为止。