偏好设置 5.1.0

偏好设置 5.1.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布上次发布2019年10月
SPM支持SPM

phimage 维护。



  • phimage

Prephirences - Preϕrences

License Platform Language Issues Cocoapod Carthage compatible Build Status

Become a Patron! Buy me a coffee

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)

⚠️ 必须导入《RawRepresentableKey》,有关设置信息,请参阅设置部分。

修改

可修改的首选项实现《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

存储原始可表示对象

对于类似于 enumRawRepresentable 对象,您可以像使用 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的对象封装在KVCPreferencesMutableKVCPreferences中。

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上使用ManageObjectPreferencesMutableManageObjectPreferences进行包装。

let managedPref = ManageObjectPreferences(myManagedObject)

Plist

有很多方法可以处理plist文件。

  • 你可以使用Plist(具有有用的write方法)。
  • 你可以使用plist文件初始化DictionaryPreferencesMutableDictionaryPreferences
  • 你可以从plist文件中读取字典,并在任何可变首选项上使用set(dictionary:

Keychain

要存储到密钥链,请使用KeychainPreferences的实例。

KeychainPreferences.sharedInstance // default instance with main bundle id
var keychain = KeychainPreferences(service: "com.github.example")

然后存储StringData

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
    }
}

只需要两个函数是强制性的,其他函数会自动映射,但可以进行重写以提高性能或可读性。

  • 同样,您可以带上 setremoveObject(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 一样访问或修改这个组合首选项。

  1. 当访问时,首先响应定义指定键值的优先级最高的首选项
  2. 当修改时,默认情况下首先影响可变的优先项,但您可以将 MutableCompositePreferences 属性 affectOnlyFirstMutable 设置为 false,以影响所有可变的优先项。这样您就可以在iCloud中复制首选项等。

主要目标是定义应用程序的只读优先级(在代码或文件中)和一些可变首选项(如 UserDefaultsNSUbiquitousKeyValueStore)。然后您可以访问单个首选项值,而不必关心其来源。

管理首选项实例

如果您想将 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"] {..}

远程首选项

使用远程首选项,您可以远程控制应用程序的行为。

如果您使用 AlamofireAlamofire-Prephirences 帮助您从远程 JSON 或 Plist 加载首选项。

加密首选项

您可以使用框架 CryptoPrephirences 使用来自 CryptoSwift 的密码来加密/解密您的首选项。

设置

使用 Cocoapods

CocoaPods 是 Objective-C 和 Swift 的集中式依赖关系管理工具。点击此处了解更多:[CocoaPods 指南](https://guides.cocoapods.org.cn/using/index.html)。

  1. 将项目添加到您的Podfile中。

    use_frameworks!
    
    pod 'Prephirences'
  2. 运行pod install并打开.xcworkspace文件,以启动Xcode。

关于Core Data

添加pod 'Prephirences/CoreData'

关于RawRepresentable key

添加pod 'Prephirences/RawRepresentableKey'

关于PropertyListKeys

添加pod 'Prephirences/Keys'

使用Carthage

Carthage是为Objective-C和Swift提供去中心化依赖关系管理器。

  1. 将项目添加到您的Cartfile

    github "phimage/Prephirences"
    
  2. 运行carthage update,并根据附加步骤将Prephirences添加到您的项目中。

使用xcode项目

  1. 将Prephirences.xcodeproj拖放到您的项目/工作区中,或将其打开以进行编译。
  2. 将Prephirences框架添加到您的项目中。

Logo

kodlian 提供