Swift里我用这个姿式写UserDefaults

人在江湖飘,总免不了要存一些值到UserDefaults。swift

UserDefaults.standard.set("@没故事的卓同窗", forKey: "Author")

let author = UserDefaults.standard.value(forKey: "Author")复制代码

有存就有取,还可能有不少地方会取这个值。这样的话每次写这个 key 就有点蛋疼了。
app

key 写成一个全局的常量虽然解决了代码重复的问题,可是体验上仍是没有改变。一个 app 里也有很多的字符串常量,怎么代表这个字符串是用于持久化的 key 呢?函数

解决方案

利用 rawValue 类型为 String 的枚举做为 key,经过协议为指定枚举增长存取到 UserDefaults 的能力。
首先声明一个枚举,建议在UserDefaults的扩展里写,固然若是你想要省掉前面一个命名空间也是能够的:spa

extension UserDefaults {
    enum TestData: String,UserDefaultSettable {
        case name
    }
}复制代码

注意到这个枚举须要实现UserDefaultSettable协议。
接着就能够在这个枚举里调用store(value: )方法来存储:code

UserDefaults.TestData.name.store(value: "name")
 let storeValue = UserDefaults.TestData.name.storedString复制代码

这个枚举TestData.name能够理解为一张银行卡。拿着这张卡到银行,说我要存,就够了。这个枚举就是一个ID。cdn

这个思路和Swift 3之后的通知中心形式类似。
blog


Notification.Name 也是一个 rawValue 为字符串的枚举。

extension NSNotification {
    public struct Name : RawRepresentable, Equatable, Hashable, Comparable {

        public init(_ rawValue: String)

        public init(rawValue: String)
    }
}复制代码

固然严格的说并非一个枚举,只是和枚举同样实现了RawRepresentable协议。不过我以为直接声明一个枚举在这里会比实现RawRepresentable便捷一些。字符串

实现

主要就是UserDefaultSettable协议的扩展了。get

public protocol UserDefaultSettable {
    var uniqueKey: String { get }
}

public extension UserDefaultSettable where Self: RawRepresentable, Self.RawValue == String {

    public func store(value: Any?){
        UserDefaults.standard.set(value, forKey: uniqueKey)
    }

    public var storedValue: Any? {
        return UserDefaults.standard.value(forKey: uniqueKey)
    }

    // 为全部的key加上枚举名做为命名空间,避免重复
    public var uniqueKey: String {
        return "\(Self.self).\(rawValue)"
    }

    public func store(value: Bool) {
        // ......
    }
    public var storedBool: Bool {
              // ......
    }
    // 还有支持其余存储类型的函数,就不全写了
}复制代码

主要的实现代码很简单,就是为 RawValue 为 String 的枚举添加了 store 和 获取存储 value 的方法。string

为了不直接取枚举的名字做为key可能引发的重名,声明了一个计算属性来生成存储的 key,规则就是加上枚举 Type 名做为前缀。好比上面的例子里存储的 key 就是 TestData.name 。

欢迎关注个人微博:@没故事的卓同窗


参考连接:
Swift: UserDefaults Protocol
UserDefault 数据存储和读取简易封装

相关文章
相关标签/搜索