Swift 里我用這個姿勢寫 UserDefaults

JerrellDoll 7年前發布 | 16K 次閱讀 Swift Apple Swift開發

人在江湖飄,總免不了要存一些值到UserDefaults。

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

let author = UserDefaults.standard.value(forKey: "Author")

有存就有取,還可能有很多地方會取這個值。這樣的話每次寫這個 key 就有點蛋疼了。

key 寫成一個全局的常量雖然解決了代碼重復的問題,但是體驗上還是沒有改變。一個 app 里也有不少的字符串常量,怎么表明這個字符串是用于持久化的 key 呢?

解決方案

利用 rawValue 類型為 String 的枚舉作為 key,通過協議為指定枚舉增加存取到 UserDefaults 的能力。

首先聲明一個枚舉,建議在UserDefaults的擴展里寫,當然如果你想要省掉前面一個命名空間也是可以的:

extension UserDefaults {
    enum TestData: String,UserDefaultSettable {
        case name
    }
}

注意到這個枚舉需要實現 UserDefaultSettable 協議。

接著就可以在這個枚舉里調用 store(value: ) 方法來存儲:

UserDefaults.TestData.name.store(value: "name")
 let storeValue = UserDefaults.TestData.name.storedString

這個枚舉 TestData.name 可以理解為一張銀行卡。拿著這張卡到銀行,說我要存,就夠了。這個枚舉就是一個ID。

這個思路和Swift 3以后的通知中心形式相似。

Notification.Name 也是一個 rawValue 為字符串的枚舉。

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

        public init(_ rawValue: String)

        public init(rawValue: String)
    }
}

當然嚴格的說并不是一個枚舉,只是和枚舉一樣實現了 RawRepresentable 協議。不過我覺得直接聲明一個枚舉在這里會比實現 RawRepresentable 便捷一些。

實現

主要就是 UserDefaultSettable 協議的擴展了。

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 的方法。

為了避免直接取枚舉的名字作為key可能引起的重名,聲明了一個計算屬性來生成存儲的 key,規則就是加上枚舉 Type 名作為前綴。比如上面的例子里存儲的 key 就是 TestData.name 。

歡迎關注我的微博:@沒故事的卓同學

參考鏈接:

Swift: UserDefaults Protocol

UserDefault 數據存儲和讀取簡易封裝

 

來自:http://www.jianshu.com/p/332ea092188e

 

 本文由用戶 JerrellDoll 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!