Swift 中 User Defaults 的讀取和寫入
前言
User Defaults 是 Swift 應(yīng)用程序存儲在應(yīng)用啟動之間保持的首選項的首選解決方案。它是由屬性列表(plist)文件支持的鍵-值存儲。由于這種類型的支持存儲,你需要了解支持的存儲類型。
在使用 User Defaults 時有一些最佳實踐。我還可以根據(jù)在數(shù)十個應(yīng)用程序中使用它的實施經(jīng)驗,推薦特定的解決方案。讓我們深入研究一下!
介紹 User Defaults
應(yīng)用程序通常使用 User Defaults 來存儲用戶的首選項。你可以存儲首選項,例如用戶最喜歡的股票或保存特定用戶狀態(tài),例如“用戶已看到引導(dǎo)”。
存儲這些首選項的代碼可以如下所示:
UserDefaults.standard.set(true, forKey: "has-seen-onboarding")
UserDefaults.standard.set(["AAPL", "TSLA"], forKey: "favorite-stocks")
print(UserDefaults.standard.bool(forKey: "has-seen-onboarding"))
// 打?。簍rue
print(UserDefaults.standard.array(forKey: "favorite-stocks"))
// 打?。篬"AAPL", "TSLA"]
在這種情況下,我們使用了標(biāo)準(zhǔn) User Defaults 容器。在大多數(shù)情況下,這將足夠。但是,你可能希望考慮使用組 User Defaults 。
共享 User Defaults
與其他應(yīng)用程序和擴展共享 User Defaults
使用所謂的應(yīng)用組,你可以與其他應(yīng)用程序和擴展共享 User Defaults 容器。我強烈建議從一開始就使用這種技術(shù),即使現(xiàn)在可能沒有共享首選項的需要,但如果你添加需要從主應(yīng)用程序中讀取或?qū)懭胧走x項的擴展,以后你會感謝自己的。
要配置應(yīng)用組,你需要向項目設(shè)置中添加一個新的功能:
你可以通過添加應(yīng)用組功能來開始與其他應(yīng)用程序和擴展共享 User Defaults。
你可以在蘋果的文檔中找到詳細(xì)的說明。配置后,你可以使用組標(biāo)識符創(chuàng)建新實例:
extension UserDefaults {
static let group = UserDefaults(suiteName: "group.your.identifier")
}
現(xiàn)在,你可以通過使用靜態(tài)屬性來訪問共享的組容器:
UserDefaults.group.set(["AAPL", "TSLA"], forKey: "favorite-stocks")
任何使用相同應(yīng)用組的應(yīng)用程序或擴展現(xiàn)在都可以讀取和寫入最喜歡的股票。我在 Stock Analyzer 中使用此技術(shù),根據(jù)主應(yīng)用程序中配置的最喜歡的股票填充小部件。
User Defaults 存儲數(shù)據(jù)類型
屬性列表必須支持你存儲在 User Defaults 中的對象。只要你嘗試寫入不受支持的對象,你將立即遇到以下錯誤:
*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘Attempt to insert non-property list object UserDefaults.Stock(symbol: “AAPL”) for key last-opened-stock’
在這種情況下,我試圖存儲一個可編碼的對象:
struct Stock: Decodable {
let symbol: String
}
UserDefaults.group.set(Stock(symbol: "AAPL"), forKey: "last-opened-stock")
每當(dāng)你遇到此類異常時,你必須在存儲數(shù)據(jù)之前將數(shù)據(jù)轉(zhuǎn)換。你可以使用 JSONEncoder 將實例編碼為數(shù)據(jù),并在讀取值時解碼它。
User Defaults 支持以下類型:
- 數(shù)據(jù)
- 字符串
- 數(shù)字(NSNumber)
- 日期
- 數(shù)組
- 字典
- 布爾值
如果你的類型不在此列表中,你需要找到一種將其轉(zhuǎn)換為任何受支持類型的方法。
響應(yīng)更改
盡管你可以使用 didChangeNotification 來觀察更改,但我建議查看類似于 User Defaults Property Wrapper 的托管解決方案,用于實時監(jiān)視更改。
監(jiān)控 User Defaults 更改
在處理與 User Defaults 互動的功能時,你希望有一種實時監(jiān)視更改的方法。為解決這個問題,我在 RocketSim 中構(gòu)建了一個 User Defaults 編輯器,允許你實時編輯和監(jiān)視鍵-值對。
例如,我在以下視頻中正在開發(fā) WeTransfer 應(yīng)用程序中顯示的工具提示。工具提示應(yīng)該每位用戶只顯示一次,我希望確保 User Defaults 鍵 hasShownUploadFilesTooltip 相應(yīng)地更新。你可以通過單擊執(zhí)行按鈕并選擇 User Defaults plist 文件來打開編輯器。
RocketSim 的 User Defaults 編輯器允許你實時編輯和查看 User Defaults 值。
編輯器不斷監(jiān)視值,當(dāng)值更改時會閃爍藍(lán)色背景顏色。與此同時,我可以使用開關(guān)重置該值,并使用 RocketSim 重新啟動應(yīng)用程序,以查看工具提示是否再次顯示。
你可以想象這大大加快了測試依賴于 User Defaults 的實施的工作流程。最好的是你可以免費開始并使用標(biāo)準(zhǔn)套件測試編輯器,只需從 Mac App Store 安裝 RocketSim 即可。
覆蓋User Defaults 設(shè)置
出于調(diào)試目的覆蓋User Defaults 設(shè)置
雖然使用 RocketSim 有助于實現(xiàn)最佳更改和調(diào)試,但你可能希望在調(diào)試過程中使用方案設(shè)置來覆蓋User Defaults 設(shè)置。
考慮的替代方案
在大多數(shù)情況下,User Defaults 是一個很好的解決方案,但如果你存儲敏感數(shù)據(jù)或希望跨設(shè)備訪問數(shù)據(jù),你可能希望探索其他解決方案。
Keychain 用于安全性
User Defaults 不足以存儲敏感數(shù)據(jù)。用戶憑據(jù)、API 密鑰或其他敏感數(shù)據(jù)應(yīng)存儲在鑰匙串中。
用于跨平臺的 CloudKit
如果希望首選項可以從安裝了你的應(yīng)用程序的其他 Apple 設(shè)備訪問,請考慮使用 NSUbiquitousKeyValueStore
。它是一個類似的鍵-值存儲,但使用 iCloud 作為支持存儲。
結(jié)論
你可以使用 User Defaults 存儲首選項并在應(yīng)用啟動之間捕獲狀態(tài)。應(yīng)用組非常適合與其他應(yīng)用程序和擴展共享首選項,你需要密切關(guān)注可以存儲的數(shù)據(jù)類型。通過監(jiān)視支持存儲,你將確保沒有意外存儲的數(shù)據(jù)。當(dāng)需要跨設(shè)備訪問數(shù)據(jù)或需要存儲敏感數(shù)據(jù)時,最好查看替代解決方案。