1

原文

SwiftyUserDefaults是一个十分方便操作NSUserDefaluts的第三方库,整个库的代码不是很多。我们学习一下。
整个库呢基本上就是对NSUserDefaults的扩展。

NSUserDefaults的基础上扩展了三个类:

class Proxy:

这个类里定义了两个存储属性 let defaults: NSUserDefaultslet key: String 和多个计算属性,一个处初始化方法。这些计算属性都是通过提供的key值来获取存储的值,返回的都是可选类型。另外一些返回的不是可选值都是在为nil时提供了默认值。

在这里通过给NSUserDefaults扩展了一个方法, numberForKey(key: String) -> NSNumber?来使数字类型的值可以转成你所需要的如IntDoubleBool等确定类型的值。

在这个类中实现了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

这里呢我只是对这个库进行了简单的说明,具体的你可以看看源码。


dowhilenet
654 声望10 粉丝