IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    用 SwiftyUserDefaults 操作 NSUserDefaluts

    这块显卡有点冷发表于 2015-12-03 16:31:53
    love 0

    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

    这里呢我只是对这个库主要一些思想进行了说明,具体的你可以看看源码。



沪ICP备19023445号-2号
友情链接