目前我:
// Save
defaults.set(Settings.hostname, forKey: "hostname")
defaults.set(Settings.current_user, forKey: "current_user")
defaults.set(Settings.access_token, forKey: "access_token")
// Load
Settings.hostname = defaults.string(forKey: "hostname")
Settings.current_user = defaults.string(forKey: "current_user")
Settings.access_token = defaults.string(forKey: "access_token")
每个人都会didSet
调用save
。
但这似乎是糟糕的设计。所以现在我正在尝试用enum
,struct
写一个值为类型的数组和一个数组:
enum SettingsKeys: Int {
case hostname = 0
case current_user
case access_token
static let count: Int = {
var max: Int = 0
while let _ = SettingsKeys(rawValue: max) { max += 1 }
return max
}()
}
struct TypeValue {
type: // TODO
}
class Settings: Loopable {
private static var settings = [Any?](repeating: nil, count: SettingsKeys.count);
//...
但这看起来很糟糕,可能不是斯威夫特。
我是如何保存/加载在整个应用中使用的设置?
答案 0 :(得分:1)
我会将SettingsKey
设为String
枚举,而不是Int
,然后编写一个类来使用键加载和保存值。原始价值。
class Settings {
static let standard = Settings()
enum SettingsKeys: String {
case hostname
case current_user
case access_token
}
private func object<T>(forKey: SettingsKey) -> T? {
return UserDefaults.standard.object(forKey: key.rawValue) as? T
}
private func set<T>(_ value: T, forKey key: SettingsKey) {
UserDefaults.standard.set(value, forKey: key.rawValue)
}
static var hostname: String {
get { return self.object(forKey: .hostname) }
set { self.set(newValue, forKey: .hostname) }
}
// etc for other values
}
请注意,如果没有正确迁移,您可能无法更改版本之间的枚举键名称。
如果您有许多相同类型的设置(例如String
),那么最好将它们组合成下标运算符:
subscript(_ key: StringKeys) -> String {
get { return self.object(forKey: key) ?? "uh oh" }
set { self.set(newValue, forKey: key) }
}
答案 1 :(得分:0)
我删除了Core Data代码,因为您的问题没有提及与Core Data相关的任何内容,但仍然没有。
要将某些内容保存到用户默认值,数据结构中的所有内容都必须是属性列表类型。那个数组,字典,字符串,日期,数字,布尔值和二进制数据blob(Swift中的Data
)。此外,字典键必须是字符串。您无法直接编写枚举或结构,您需要将它们转换为仅需要属性列表类型的其他形式。
一种方法是将设置放在结构中,然后依靠Codable
将结构转换为/ Data
::
struct Settings : Codable {
var hostname:String
var current_user:String
var access_token:String
}
let mySettings = Settings(hostname: "hostfoo", current_user: "userfoo", access_token: "accessfoo")
let encoder = JSONEncoder()
let mySettingsData = try? encoder.encode(mySettings)
UserDefaults.standard.set(mySettingsData, forKey: "data")
使用核心数据是没有意义的,除非你有多个设置集合,一次将它们全部读入内存是很尴尬的。您提到的自动序列化可能是Core Data&#34; transformable&#34;属性类型。如果值符合Data
协议,则可以自动将转换转换为NSCoding
。但NSCoding
需要对象,而不是结构或枚举或其他任何东西,而且只适用于继承自NSObject
的类。