SwiftyUserDefaults是一个十分方便操作NSUserDefaluts
的第三方库,整个库的代码不是很多。我们学习一下。
整个库呢基本上就是对NSUserDefaults
的扩展。
在NSUserDefaults
的基础上扩展了三个类:
class Proxy
:
这个类里定义了两个存储属性 let defaults: NSUserDefaults
和 let key: String
和多个计算属性,一个处初始化方法。这些计算属性都是通过提供的key
值来获取存储的值,返回的都是可选类型。另外一些返回的不是可选值都是在为nil
时提供了默认值。
在这里通过给NSUserDefaults
扩展了一个方法, numberForKey(key: String) -> NSNumber?
来使数字类型的值可以转成你所需要的如Int
,Double
,Bool
等确定类型的值。
在这个类中实现了subscript
,我们可以通过下标来获取对应的key
的值。
这个类呢从名字,既可以看出来他是一个代理类,其它类通过它来实现对键值对的操作。
class DefaultsKeys
这是一个空的类,主要是用来让用户调用。使用户通过一种更佳优雅的方式来添加获取键 -- 值
。
例如:
extension DefaultsKeys {
static let username = DefaultsKey<String?>("username")
static let launchCount = DefaultsKey<Int>("launchCount")
}
我们通过扩展这个类来让用户添加Key
,这样做有什么好处呢?我们可以把所有的Key
都存放在这里,方便我们查看。还有就是获取值和赋值时也很方便
Defaults[.username] = "joe"
Defaults[.launchCount]
通过上边的例子我们可以看到我们使用了DefaultsKey
这个类,这个类是我们接下来我介绍的。
在这里你只需要知道的是,我们通过扩展DefaultsKeys
,给他添加类属性来保存我们的Key
class DefaultsKey<ValueType>: DefaultsKeys
这个类是我们最为重要的一个类了,你可以看出来它继承自DefaultsKeys
这个类。为什么要继承DefaultsKeys
这个类呢,应为,如果你通过扩展DefaultsKeys
来添加你的Key
的话,在DefaultsKey
这个类就可以直接使用你的Key
来进行接下来的操作。
那么DefaultsKey
这个类都实现了什么功能?不妨我们先看看是怎么使用它的吧。
let colorKey = DefaultsKey<String>("color") // 定义了你的key
Defaults[colorKey] = "red"
Defaults[colorKey] // => "red", typed as String
你可能会觉得DefaultsKey<String>("color")
这样的类初始化方法没有怎么见过。这是因为,DefaultsKey
这个类是一个泛型类型。
public class DefaultsKey<ValueType>: DefaultsKeys {
public let _key: String
public init(_ key: String) {
self._key = key
}
}
可以看到这个类呢只有一个存储类型属性,来保存我们的key
,下边的方法都试通过这个key
值来进行操作。
我们可以通过 key 来获取和设置对应的值。在实现这些操作前,我们还要来为NSUserDefaults
扩展一个方法
extension NSUserDefaults {
func set<T>(key: DefaultsKey<T>, _ value: Any?) {
self[key._key] = value
}
}
这个方法的将一个Any
类型的值类存储到对应的key。
self[key._key] = value
调用的是上边实现的下标
public subscript(key: String) -> Any? {
get {
return self[key]
}
set {
switch newValue {
case let v as Int: setInteger(v, forKey: key)
case let v as Double: setDouble(v, forKey: key)
case let v as Bool: setBool(v, forKey: key)
case let v as NSURL: setURL(v, forKey: key)
case let v as NSObject: setObject(v, forKey: key)
case nil: removeObjectForKey(key)
default: assertionFailure("Invalid value type")
}
}
}
接下来就是要实现通过key来获取我们所需要的值,这里呢也是通过对NSUserDefaults
扩展下标来获取对应的key的值。
extension NSUserDefaults {
public subscript(key: DefaultsKey<String?>) -> String? {
get { return stringForKey(key._key) }
set { set(key, newValue) }
}
....
这里重载的方法较多,只拿出一个来讲解。
这里你可以看到DefaultsKey<String?>
和我们的返回类型是对应起来的String?
,这也就是说为什么我们在刚才使用的时候,不用指明你要获取的值的类型,因为你在定义键的时候其实也就定义了你将来要获取的值的类型。但是如果你是通过下边的这种方法来获取值的话,就需要指明类型了。
Defaults["color"].string // returns String?
Defaults["launchCount"].int // returns Int?
Defaults["chimeVolume"].double // returns Double?
public let Defaults = NSUserDefaults.standardUserDefaults()
是一个全局变量,你可以在你需要它的任何地方使用。
自定义类型
通过对NSUserDefaults
的扩展来实现自定义类型的存储。
extension NSUserDefaults {
public func archive<T>(key: DefaultsKey<T>, _ value: T) {
if let value: AnyObject = value as? AnyObject {
set(key, NSKeyedArchiver.archivedDataWithRootObject(value))
} else {
assertionFailure("Invalid value type")
}
}
public func archive<T>(key: DefaultsKey<T?>, _ value: T?) {
if let value: AnyObject = value as? AnyObject {
set(key, NSKeyedArchiver.archivedDataWithRootObject(value))
} else if value == nil {
remove(key)
} else {
assertionFailure("Invalid value type")
}
}
public func unarchive<T>(key: DefaultsKey<T?>) -> T? {
return dataForKey(key._key).flatMap { NSKeyedUnarchiver.unarchiveObjectWithData($0) } as? T
}
public func unarchive<T>(key: DefaultsKey<T>) -> T? {
return dataForKey(key._key).flatMap { NSKeyedUnarchiver.unarchiveObjectWithData($0) } as? T
}
}
例子:
extension NSUserDefaults {
subscript(key: DefaultsKey<NSColor?>) -> NSColor? {
get { return unarchive(key) }
set { archive(key, newValue) }
}
}
extension DefaultsKeys {
static let color = DefaultsKey<NSColor?>("color")
}
Defaults[.color] // => nil
Defaults[.color] = NSColor.whiteColor()
Defaults[.color] // => w 1.0, a 1.0
Defaults[.color]?.whiteComponent // => 1.0
这里呢我只是对这个库进行了简单的说明,具体的你可以看看源码。