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 數據存儲和讀取簡易封裝

相關文章
相關標籤/搜索