- 原文地址:Let’s Simplify the Work with UserDefaults
- 原文作者:Nikita Ermolenko
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:talisk
- 校對者:allen,stormluke
每個人都用 UserDefaults 來儲存一些簡單的資料,並且知道使用該儲存很容易。但是今天我會改善一點它的互動性!讓我們從最明顯的解決方案開始,並實現一些新穎且優雅的東西。?
想象一下我們有一個服務 —— SettingsService。這個服務掌握了應用的設定 —— 正在使用哪個主題(黑暗,明亮),是否啟用通知等等。為了實現它,大多數開發人員會首先考慮 UserDefaults。 當然,用哪種方式取決於具體情況,但先讓我們來簡化 UserDefaults。
- 我們的第一個最簡方案
class SettingsService {
private enum Keys {
static let isNotificationsEnabled = "isNotificationsEnabled"
}
var isNotificationsEnabled: Bool {
get {
let isEnabled = UserDefaults.standard.value(forKey: Keys.isNotificationsEnabled) as? Bool
return isEnabled ?? true
}
set {
UserDefaults.standard.setValue(newValue, forKey: Keys.isNotificationsEnabled)
}
}
}
複製程式碼
為了簡單化,我直接使用 UserDefaults.standard
,但在一個真實專案中,你最好把它存到一個 property 中,並使用依賴注入。
- 下一步,我想要擺脫 Keys 列舉——使用
#function
來代替:
class SettingsService {
var isNotificationsEnabled: Bool {
get {
let isEnabled = UserDefaults.standard.value(forKey: #function) as? Bool
return isEnabled ?? true
}
set {
UserDefaults.standard.setValue(newValue, forKey: #function)
}
}
}
複製程式碼
看,怎麼樣!讓我們繼續:)
- 下標時間!我們剛剛把
value(forKey:)
方法封裝成支援範型的下標語法形式:
extension UserDefaults {
subscript<T>(key: String) -> T? {
get {
return value(forKey: key) as? T
}
set {
set(newValue, forKey: key)
}
}
}
class SettingsService {
var isNotificationsEnabled: Bool {
get {
return UserDefaults.standard[#function] ?? true
}
set {
UserDefaults.standard[#function] = newValue
}
}
}
複製程式碼
它看起來已經很整潔了!但是 Enums 呢??
enum AppTheme: Int {
case light
case dark
}
class SettingsService {
var appTheme: AppTheme {
get {
if let rawValue: AppTheme.RawValue = UserDefaults.standard[#function], let theme = AppTheme(rawValue: rawValue) {
return theme
}
return .light
}
set {
UserDefaults.standard[#function] = newValue.rawValue
}
}
}
複製程式碼
這裡可以重構!
- 讓我們為 RawRepresentable 值編寫一個類似的 subscript:
extension UserDefaults {
subscript<T: RawRepresentable>(key: String) -> T? {
get {
if let rawValue = value(forKey: key) as? T.RawValue {
return T(rawValue: rawValue)
}
return nil
}
set {
set(newValue?.rawValue, forKey: key)
}
}
}
class SettingsService {
var appTheme: AppTheme {
get {
return UserDefaults.standard[#function] ?? .light
}
set {
UserDefaults.standard[#function] = newValue
}
}
}
複製程式碼
馬上完成啦!請注意,此擴充套件僅適用於使用 RawRepresentable 的列舉。
別忘了訂閱我的 telegram channel!第一時間瞭解 iOS 世界的有趣新聞和文章!
希望你能喜歡我寫的 extension!如果你有任何改進它的想法請告訴我!檢視 UserDefaults 的最新版本 extension 盡情地體驗一下吧:)
這就是在構建 ITC 時候的我
一個在 Rosberry 工作的毛髮濃密的 iOS 工程師。熱衷響應式程式設計,開源愛好者,迴圈引用檢測人。:)
感謝 Evgeny Mikhaylov 和 Rosberry。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。