Prephirences - Preϕrences
Prephirences是一个Swift库,它提供了有用的协议和便捷方法来管理应用程序首选项、配置和应用状态。
@Preference(key: "enabled")
var enabled: Bool?
@UserDefaultsPreference(key: "my.string.pref")
var pref: String?
@MutablePreference(preferences: UserDefaults.standard, key: "enabled")
var enabled: Bool?
let userDefaults = UserDefaults.standard
if let enabled = userDefaults["enabled"] as? Bool {..}
userDefaults["mycolorkey", archive] = UIColor.blue
偏好设置不仅是UserDefaults
,还可以是
- 密钥链存储凭据
- 任何字典
- 来自
Bundle
的应用程序信息 - 存储的文件偏好设置(例如:属性列表)
- iCloud存储的偏好设置
NSUbiquitousKeyValueStore
- 或您自己的私有应用程序首选项
即。任何实现简单协议的对象 PreferencesType,该协议定义了键值存储方法。
您还可以组合多个首选项并与它们透明地工作(请参阅组合)
内容
用法
创建
《PreferencesType》的最简单实现是《PreferencesType》。
// From Dictionary
var fromDico = DictionaryPreferences(myDictionary)
// or literal
var fromDicoLiteral: DictionaryPreferences = ["myKey": "myValue", "bool": true]
// From filepath
if let fromFile = DictionaryPreferences(filePath: "/my/file/path") {..}
// ...in main bundle ##
if let fromFile = DictionaryPreferences(filename: "prefs", ofType: "plist") {..}
访问
您可以使用《PreferencesType》协议中定义的所有方法进行访问。
if let myValue = fromDicoLiteral.object(forKey: "myKey") {..}
if let myValue = fromDicoLiteral["bool"] as? Bool {..}
var hasKey = fromDicoLiteral.hasObject(forKey: "myKey")
var myValue = fromDicoLiteral.bool(forKey: "myKey")
..
如果您想使用《code>RawRepresentable enum
访问。
enum MyKey: PreferenceKey/*String*/ {
case Key1, Key2, ...
}
if let myValue = fromDicoLiteral.object(forKey: MyKey.Key1) {..}
var myValue = fromDicoLiteral.bool(forKey: MyKey.Key2)
修改
可修改的首选项实现《MutablePreferencesTypes》协议
最简单实现是《MutableDictionaryPreferences》。
var mutableFromDico: MutableDictionaryPreferences = ["myKey": "myValue"]
mutableFromDico["newKey"] = "newValue"
mutableFromDico.set("myValue", forKey: "newKey")
mutableFromDico.set(true, forKey: "newKey")
...
您可以使用操作符添加字典或其他《code>PreferencesType。
mutableFromDico += ["newKey": "newValue", "otherKey": true]
您也可以移除一个首选项
mutableFromDico -= "myKey"
对一个首选项应用操作符
您可以从任何《code>MutablePreferencesTypes中提取出《code>MutablePreference,并根据其值类型应用操作符。
var intPref: MutablePreference<Int> = aPrefs.preference(forKey: "intKey")
var intPref: MutablePreference<Int> = aPrefs <| "intKey"
intPref++
intPref--
intPref += 30
intPref -= 30
intPref *= 20
intPref %= 7
intPref /= 3
switch(intPref) {
case 1: println("one")
case 2...10: println("not one or zero but...")
default: println("unkwown")
}
var boolPref: MutablePreference<Bool> = aPrefs <| "boolKey")
boolPref &= false
boolPref |= true
boolPref != true
您还可以使用一些方法来更改值
var stringPref: MutablePreference<String> = userDefaults <| "stringKey"
stringPref.apply { value in
return value?.uppercaseString
}
或使用闭包转换值类型
let intFromBoolPref : MutablePreference<Int> = boolPref.transform { value in
return (value ?? false) ? 1:0
}
转换和归档
在存储或访问值之前,可以进行转换,这些转换符合 PreferenceTransformation
协议。
这允许归档、更改类型、如果为空返回默认值等。
您可以使用 subscript
来获取和设置值。
userDefaults["aKey", myTransformation] = myObject
if let object = userDefaults["aKey", myTransformation] {...}
如果您提取一个首选项,使用 transformation
属性来设置转换
var aPref: MutablePreference<MyObject> = userDefaults <| "aKey"
aPref.transformation = myTransformation
或者您可以使用一些实用函数来指定一个默认值,当存储的值符合某个条件时
public var intValueMin10: MutablePreference<Int> {
get {
return userDefaults.preference(forKey: "intKey")
.whenNil(use: 100)
.ensure(when: lessThan100, use: 100)
}
set {..}
}
归档
归档在配合 NSUserDefaults
特别有用,因为 NSUserDefaults
无法存储所有类型的对象。以下函数通过将值转换为其他类型来提供帮助:
您可以使用以下两种方法存档到 Data
:
userDefaults.set(objectToArchive: UIColor.blueColor(), forKey: "colorKey")
userDefaults["colorKey", .Archive] = UIColor.blueColor()
并使用以下方法解档:
if let color = userDefaults.unarchiveObject(forKey: "colorKey") as? UIColor {..}
if let color = userDefaults["colorKey", .Archive] as? UIColor {..}
如果您提取一个首选项,使用 transformation
属性来设置归档模式
var colorPref: MutablePreference<UIColor> = userDefaults <| "colorKey"
colorPref.transformation = TransformationKey.Archive
colorPref.value = UIColor.redColor()
if let color = colorPref.value as? UIColor {..}
NSValueTransformer
您也可以为所有对象类型提供 NSValueTransformer
,例如将其转换为 JSON
userDefaults["colorKey", myValueTransformerToJson] = myComplexObject
if let object = userDefaults["colorKey", myValueTransformerToJson] {...}
allowsReverseTransformation
必须返回 true
存储原始可表示对象
对于类似于 enum
的 RawRepresentable
对象,您可以像使用 transformation
一样使用计算属性 preferenceTransformation
enum PrefEnum: String {
case One, Two, Three
}
var pref: MutablePreference<PrefEnum> = preferences <| "enumKey"
pref.transformation = PrefEnum.preferenceTransformation
pref.value = PrefEnum.Two
一些实现
UserDefaults
UserDefaults
实现PreferencesType
并且可以以相同的方法访问。
let userDefaults = UserDefaults.standard
if let myValue = userDefaults["mykey"] as? Bool {..}
NSUserDefaults也实现了MutablePreferencesType
,可以用相同的方法进行修改。
userDefaults["mykey"] = "myvalue"
// with type to archive
userDefaults["mykey", .Archive] = UIColor.blueColor()
Bundle
所有Bundle
都实现了PreferencesType
,允许访问Info.plist文件。
例如,Bundle.main
包含有关您的应用程序的许多有用信息。
Preferences框架附带了一些预定义枚举,这些枚举在Apple文档中描述,并在PropertyListKeys.swift
中定义。
let bundle = Bundle.main
let applicationName = bundle[.CFBundleName] as? String
NSUbiquitousKeyValueStore
要存储在iCloud中,NSUbiquitousKeyValueStore
也实现了PreferencesType
。
请参阅合成章节,了解如何合并和同步iCloud首选项与其他首选项。
键值编码
Foundation类
您可以将响应隐式协议NSKeyValueCoding的对象封装在KVCPreferences
或MutableKVCPreferences
中。
let kvcPref = MutableKVCPreferences(myObject)
确保影响正确的对象类型。
Swift类
使用ReflectingPreferences
可以轻松访问结构体或Swift类。只需添加扩展。
struct PreferenceStruct {
var color: String = "red"
var age: Int
let enabled: Bool = true
}
extension PreferenceStruct: ReflectingPreferences {}
然后你可以使用PreferencesType
的所有功能。
var pref = PreferenceStruct(color: "red", age: 33)
if pref["color"] as? String { .. }
Core Data
你可以在NSManageObject
上使用ManageObjectPreferences
或MutableManageObjectPreferences
进行包装。
let managedPref = ManageObjectPreferences(myManagedObject)
Plist
有很多方法可以处理plist文件。
- 你可以使用
Plist
(具有有用的write
方法)。 - 你可以使用plist文件初始化
DictionaryPreferences
或MutableDictionaryPreferences
。 - 你可以从plist文件中读取字典,并在任何可变首选项上使用
set(dictionary:
。
Keychain
要存储到密钥链,请使用KeychainPreferences
的实例。
KeychainPreferences.sharedInstance // default instance with main bundle id
var keychain = KeychainPreferences(service: "com.github.example")
然后存储String
或Data
。
keychain["anUserName"] = "password-encoded"
if let pass = keychain.stringForKey("anUserName") {..}
辅助功能
keychain.accessibility = .AccessibleAfterFirstUnlock
共享密钥链项
keychain.accessGroup = "AKEY.shared"
NSCoder
NSCoder
部分支持(dictionary
不可用)。
当你实现NSCoding协议时,你可以做
init?(coder decoder: NSCoder) {
self.init()
self.intVar = decoder["intVarKey"] as? Int ?? 0
// or self.intVar = decoder.integer(forKey: "intVar")
self.stringVar = decoder["stringVarKey"] as? String ?? ""
}
func encodeWithCoder(coder: NSCoder) {
coder["intVarKey"] = self.intVar
coder["stringVarKey"] = self.stringVar
}
自定义实现
首选项
创建一个符合 PreferencesType
的自定义对象非常简单。
extension MyCustomPreferences: PreferencesType {
func object(forKey: String) -> Any? {
// return an object according to key
}
func dictionary() -> [String : Any] {
// return a full dictionary of key value
}
}
只需要两个函数是强制性的,其他函数会自动映射,但可以进行重写以提高性能或可读性。
- 同样,您可以带上
set
和removeObject(forKey:
方法来实现MutablePreferencesType
。 - 如果您提供一个键列表而不是完整的字典,您可以选择实现
PreferencesAdapter
并实现func keys() -> [String]
。 - 您可以查看每个对象都可以定义一个键和一个值的对象集合,查看
CollectionPreferencesAdapter
或查看NSHTTPCookieStorage
的实现。
使用自定义键访问
您可以使用 enum
来定义一个键列表,而不是使用字符串或字符串常量。
首先使用 String
原始值创建您的 enum
enum MyEnum: String {
case MyFirstKey
case MySecondKey
}
然后添加对您的键的索引器
extension PreferencesType {
subscript(key: MyEnum) -> Any? {
return self[key.rawValue]
}
}
最后访问您的信息
if let firstValue = bundle[.MyFirstKey] {..}
您还可以对 MutablePreferencesType
执行相同的操作
使用前缀代理首选项
您可以使用自己的字符串前缀定义首选项子类别,如下所示
let myAppPrefs = MutableProxyPreferences(preferences: userDefaults, key: "myAppKey.")
// We have :
userDefaults["myAppKey.myKey"] == myAppPrefs["myKey"] // is true
这允许您使用相同的首部键为所有首选项(首选项)前缀
组合
组合允许将多个 PreferencesType
对象聚合到一个 PreferencesType
中
let myPreferences = CompositePreferences([fromDico, fromFile, userDefaults])
// With array literal
let myPreferences: CompositePreferences = [fromDico, fromFile, userDefaults]
// Mutable, only first mutable will be affected
let myPreferences: MutableCompositePreferences = [fromDico, fromFile, userDefaults]
您可以像访问或修改任何 PreferencesType
一样访问或修改这个组合首选项。
- 当访问时,首先响应定义指定键值的优先级最高的首选项
- 当修改时,默认情况下首先影响可变的优先项,但您可以将
MutableCompositePreferences
属性affectOnlyFirstMutable
设置为false
,以影响所有可变的优先项。这样您就可以在iCloud中复制首选项等。
主要目标是定义应用程序的只读优先级(在代码或文件中)和一些可变首选项(如 UserDefaults
、NSUbiquitousKeyValueStore
)。然后您可以访问单个首选项值,而不必关心其来源。
管理首选项实例
如果您想将 Prephirences 集成到一个框架中,或者想在类之间不添加依赖关系的情况下获取一个 Preferences
,可以将任何 PreferencesType
注册到 Prephirences
中
作为共享实例
Prephirences.sharedInstance = myPreferences
或通过提供一个 Hashable
键
Prephirences.register(preferences: myPreferences, forKey: "myKey")
Prephirences.instances()["myKey"] = myPreferences
Prephirences.instances()[NSStringFromClass(self.dynamicType)] = currentClassPreferences
然后您可以从任何地方访问它
if let pref = Prephirences.instance(forKey: "myKey") {..}
if let pref = Prephirences.instances()["myKey"] {..}
远程首选项
使用远程首选项,您可以远程控制应用程序的行为。
如果您使用 Alamofire,Alamofire-Prephirences 帮助您从远程 JSON 或 Plist 加载首选项。
加密首选项
您可以使用框架 CryptoPrephirences 使用来自 CryptoSwift 的密码来加密/解密您的首选项。
设置
使用 Cocoapods
CocoaPods 是 Objective-C 和 Swift 的集中式依赖关系管理工具。点击此处了解更多:[CocoaPods 指南](https://guides.cocoapods.org.cn/using/index.html)。
-
将项目添加到您的Podfile中。
use_frameworks! pod 'Prephirences'
-
运行
pod install
并打开.xcworkspace
文件,以启动Xcode。
关于Core Data
添加pod 'Prephirences/CoreData'
关于RawRepresentable key
添加pod 'Prephirences/RawRepresentableKey'
关于PropertyListKeys
添加pod 'Prephirences/Keys'
使用Carthage
Carthage是为Objective-C和Swift提供去中心化依赖关系管理器。
使用xcode项目
- 将Prephirences.xcodeproj拖放到您的项目/工作区中,或将其打开以进行编译。
- 将Prephirences框架添加到您的项目中。
Logo
由 kodlian 提供