SafeDefaultsKit
一个用于安全访问 UserDefaults 的纯 Swift 库
要求
- Xcode 9
- Swift 4.0+
- iOS 10.0+
安装
CocoaPods
CocoaPods 是 Cocoa 项目的一个依赖管理器。
要使用 CocoaPods 将 SafeDefaultsKit 集成到您的 Xcode 项目中,请将以下行添加到您的 Podfile
并运行 pod install
。
pod 'SafeDefaultsKit', git: 'https://github.com/jrsaruo/SafeDefaultsKit.git'
Carthage
Carthage 是一个去中心化的依赖管理器,它会构建你的依赖项并提供二进制框架。
要使用 Carthage 将 SafeDefaultsKit 集成到您的 Xcode 项目中,请在您的 Cartfile
中指定它
github "jrsaruo/SafeDefaultsKit"
运行 carthage update
来构建框架,并将构建好的 SafeDefaultsKit.framework
拖动到您的 Xcode 项目中。
功能
使用枚举作为键进行安全访问
您可以使用原始键并通过它们安全地访问 UserDefaults
。
// Initialize your Defaults
let defaults = YourDefaults()
// Set value for Defaults
defaults.set("saved string", forKey: .definedKey)
// Get value from Defaults
print(defaults.string(forKey: .definedKey) ?? "no value") // -> "saved string"
// Remove value from Defaults
defaults.removeObject(forKey: .definedKey)
print(defaults.string(forKey: .definedKey) ?? "no value") // -> "no value"
分割默认值
通过对每个用途分割 Defaults,管理键变得更容易。
let loginInfoDefaults = LoginInfoDefaults() // LoginInfoDefaults has "loginDate" key
loginInfoDefaults.set(Date(), forKey: .loginDate)
let settingDefaults = SettingDefaults() // SettingDefaults has "mainColor" key
settingDefaults.set("red", forKey: .mainColor)
用法
首先,声明一个符合 SafeDefaults
协议的类型。这需要名为 Keys
的嵌套枚举,它符合 DefaultsKey
协议并且存储 原始字符串值,其情况用作 Defaults 的键。
最简单的声明
struct SampleDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case userName
}
}
SampleDefaults().set("Tom", forKey: .userName)
// same as: UserDefaults.standard.set("Tom", forKey: "userName")
自定义 UserDefaults 的键名
DefaultsKey
需要具有 uniqueValue
属性,用作 UserDefaults
的键名。uniqueValue
的默认值为其原始值。
struct SampleDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case userName = "customizedKeyForUserName"
}
}
SampleDefaults().set("Tom", forKey: .userName)
// same as: UserDefaults.standard.set("Tom", forKey: "customizedKeyForUserName")
如果您显式声明 uniqueValue
,则它将用作键名,而不是原始值。
struct SampleDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case userName
// customize the key name for UserDefaults
var uniqueValue: String {
return "SampleDefaults.\(Keys.self).\(self.rawValue)"
}
}
}
SampleDefaults().set("Tom", forKey: .userName)
// same as: UserDefaults.standard.set("Tom", forKey: "SampleDefaults.Keys.userName")
⚠️ 注意
与 UserDefaults 的区别
对于 double、float 和 integer 的 getter 方法返回 可选 值。如果指定的键不存在,则这些方法返回 nil
。
UserDefaults.standard.removeObject(forKey: "removed")
UserDefaults.standard.integer(forKey: "removed") // -> 0
YourDefaults().integer(forKey: .removed) // -> nil
Keys.uniqueValue 的唯一性不能完全保证
uniqueValue
用作 UserDefaults
的键名,默认值为原始值,因此有 键冲突的可能。
❌ NG 示例
struct BookDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case id
}
}
struct ComicDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case id // MARK: This uniqueValue conflicts with that of BookDefaults.Keys.id
}
}
BookDefaults().set(5, forKey: .id) // same as: UserDefaults.set(5, forKey: "id")
ComicDefaults().set(10, forKey: .id) // same as: UserDefaults.set(10, forKey: "id")
print(BookDefaults().integer(forKey: .id)!) // -> 10 (not 5)
⭕️ 避免相同的案例名称
struct BookDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case bookID
}
}
struct ComicDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case comicID
}
}
BookDefaults().set(5, forKey: .bookID) // same as: UserDefaults.set(5, forKey: "bookID")
ComicDefaults().set(10, forKey: .comicID) // same as: UserDefaults.set(10, forKey: "comicID")
print(BookDefaults().integer(forKey: .bookID)!) // -> 5
⭕️ 显式设置不同的原始值
struct BookDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case id = "bookID"
}
}
struct ComicDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case id = "comicID"
}
}
BookDefaults().set(5, forKey: .id) // same as: UserDefaults.set(5, forKey: "bookID")
ComicDefaults().set(10, forKey: .id) // same as: UserDefaults.set(10, forKey: "comicID")
print(BookDefaults().integer(forKey: .id)!) // -> 5
⭕️ 自行声明 uniqueValue
通过声明 uniqueValue
,可以自定义 UserDefaults 的键名。例如,可以使用 Defaults 的名称作为命名空间。
struct BookDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case id
var uniqueValue: String {
// use "BookDefaults.Keys" as the namespace
return "BookDefaults.\(Keys.self).\(self.rawValue)"
}
}
}
struct ComicDefaults: SafeDefaults {
enum Keys: String, DefaultsKey {
case id
var uniqueValue: String {
return "ComicDefaults.\(Keys.self).\(self.rawValue)"
}
}
}
BookDefaults().set(5, forKey: .id) // same as: UserDefaults.set(5, forKey: "BookDefaults.Keys.id")
ComicDefaults().set(10, forKey: .id) // same as: UserDefaults.set(10, forKey: "ComicDefaults.Keys.id")
print(BookDefaults().integer(forKey: .id)!) // -> 5
许可协议
SafeDefaultsKit 在 MIT 许可协议下。有关更多信息,请参阅LICENSE 文件。