如何在Swift中正确存储用户设置?

问题描述

我想知道在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之类的属性包装器。 这样就无需对值进行编码/解码,直到它成为自定义类型为止。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...