重做項目時,用UserDefaults緩存了一些簡單數(shù)據(jù),UserDefaults用的頻次稍多一點,就看到一個不太合理的現(xiàn)象。
1、每次都要完整的寫出UserDefaults.standard,然后才去存取,代碼看起來不是很整潔
2、key的管理、value的類型沒有統(tǒng)一的約束,非常散亂
然后就想到了提煉代碼。
針對問題,出兩條對策:
1、封裝UserDefaults的調(diào)用方法,縮減代碼量
2、整理key和value
之前代碼中(二手項目),是對UserDefaults.standard加了一個全局方法處理,kUserDefaultsSet這樣的寫法,簡單壓縮一下調(diào)用方法,key和value還是一盤散沙。
這種再封裝的方法意義不大,項目中還有key沒有聚合起來,隨著版本改動,這些key重復創(chuàng)建,或者隨著版本變化逐漸被遺忘在項目中不再維護,導致UserDefaults被逐漸寫爛。
后來嘗試把key整理在一個類里面,使用DefaultsKey.xxx 這樣的寫法,還是覺得不美觀。如果有新人來看項目,他就需要去看全局方法和一個常量聚合類,很不人性。
然后針對命名空間又進行優(yōu)化,引出了二級命名空間DefaultsKey.User.xxx,DefaultsKey.Home.xxx。樹壯結(jié)構(gòu)思維清晰了一些,看起來也美觀了,但上一條說的問題依然存在--UserDefaults還是得寫兩處(方法和key)。
但是,引入了命名空間的思想,意外的給解決問題帶來了靈感。
我為什么不直接在key上下功夫呢?
直接給key賦值,結(jié)合get和set,省略kUserDefaultsSet的全局方法。
然后就有了如下操作:
extension UserDefaults {
? ? struct Ex {}
}
用UserDefaults自身做命名空間擴展,方便記憶。
所有的自定義key擴展都寫在Ex下面,不會與他本身沖突
再給UserDefaults.Ex做擴展
extension UserDefaults.Ex {
? ? //用戶信息
? ? struct User {
? ? ? ? /// 用戶token
? ? ? ? static var Token : String? {
? ? ? ? ? ? get {
? ? ? ? ? ? ? ? return UserDefaults.standard.string(forKey:"user_Token")
? ? ? ? ? ? }
? ? ? ? ? ? set {
? ? ? ? ? ? ? ? UserDefaults.standard.set(newValue, forKey:"user_Token")
? ? ? ? ? ? ? ? UserDefaults.standard.synchronize()
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
User就是用戶分類,Token就是用戶的Token
調(diào)用時,就很簡單了
//存入
UserDefaults.Ex.User.Token = "1234567890"
//讀取
let token =UserDefaults.Ex.User.Token?
總結(jié):
?- 命名空間很好地解決了Key的問題,對于多個同樣子類的字段,可以創(chuàng)建二級/三級命名空間,樹狀結(jié)構(gòu)思路清晰;在外部使用點語法時會自動補全提示,調(diào)用也更加方便
- ?set和get剛好貼入UserDefaults的讀與寫,能規(guī)范value的類型,符合擴展類的設計思路
- 相對于老的寫法,此處代碼相對較多,但是Defaults本身不會存太多東西,適合放在一個單獨的文件中管理,什么時候新增或者棄用值都是一眼能看出來的,并且這種做法思路清晰,結(jié)構(gòu)安全