Skip to content

Commit 1f63600

Browse files
authored
Merge pull request #19204 from wordpress-mobile/task/jp-shared-defaults-refactor
UserPersistentStore: Refactor & Replace existing `standard` calls
2 parents e213be2 + 8af2c72 commit 1f63600

27 files changed

Lines changed: 108 additions & 76 deletions

WordPress/Classes/Models/UserSettings.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct UserSettings {
2626

2727
/// Reset all UserSettings back to their defaults
2828
static func reset() {
29-
UserSettings.Keys.allCases.forEach { UserDefaults.standard.removeObject(forKey: $0.rawValue) }
29+
UserSettings.Keys.allCases.forEach { UserPersistentStoreFactory.instance().removeObject(forKey: $0.rawValue) }
3030
}
3131
}
3232

@@ -58,10 +58,10 @@ struct UserDefault<T> {
5858

5959
var wrappedValue: T {
6060
get {
61-
return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
61+
return UserPersistentStoreFactory.instance().object(forKey: key) as? T ?? defaultValue
6262
}
6363
set {
64-
UserDefaults.standard.set(newValue, forKey: key)
64+
UserPersistentStoreFactory.instance().set(newValue, forKey: key)
6565
}
6666
}
6767
}
@@ -77,13 +77,13 @@ struct NullableUserDefault<T> {
7777

7878
var wrappedValue: T? {
7979
get {
80-
return UserDefaults.standard.object(forKey: key) as? T
80+
return UserPersistentStoreFactory.instance().object(forKey: key) as? T
8181
}
8282
set {
8383
if let newValue = newValue {
84-
UserDefaults.standard.set(newValue, forKey: key)
84+
UserPersistentStoreFactory.instance().set(newValue, forKey: key)
8585
} else {
86-
UserDefaults.standard.removeObject(forKey: key)
86+
UserPersistentStoreFactory.instance().removeObject(forKey: key)
8787
}
8888
}
8989
}

WordPress/Classes/Services/NotificationSettingsService.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ open class NotificationSettingsService: LocalCoreDataService {
7878

7979
for key in NotificationSettings.locallyStoredKeys {
8080
let userDefaultsKey = userDefaultsKey(withNotificationSettingKey: key, for: blog)
81-
let value = (UserDefaults.standard.value(forKey: userDefaultsKey) as? Bool) ?? true
81+
let value = (UserPersistentStoreFactory.instance().object(forKey: userDefaultsKey) as? Bool) ?? true
8282

8383
localSettings[key] = value
8484
}
@@ -89,7 +89,7 @@ open class NotificationSettingsService: LocalCoreDataService {
8989
private func saveLocalSettings(_ settings: [String: Bool], blog: Blog) {
9090
for (key, value) in settings {
9191
if NotificationSettings.isLocallyStored(key) {
92-
UserDefaults.standard.set(value, forKey: userDefaultsKey(withNotificationSettingKey: key, for: blog))
92+
UserPersistentStoreFactory.instance().set(value, forKey: userDefaultsKey(withNotificationSettingKey: key, for: blog))
9393
}
9494
}
9595
}

WordPress/Classes/Stores/RemoteFeatureFlagStore.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ extension RemoteFeatureFlagStore {
7373
/// The `deviceID` ensures we retain a stable set of Feature Flags between updates. If there are staged rollouts or other dynamic changes
7474
/// happening server-side we don't want out flags to change on each fetch, so we provide an anonymous ID to manage this.
7575
private var deviceID: String {
76-
guard let deviceID = UserDefaults.standard.string(forKey: Constants.DeviceIdKey) else {
76+
guard let deviceID = UserPersistentStoreFactory.instance().string(forKey: Constants.DeviceIdKey) else {
7777
DDLogInfo("🚩 Unable to find existing device ID – generating a new one")
7878
let newID = UUID().uuidString
79-
UserDefaults.standard.set(newID, forKey: Constants.DeviceIdKey)
79+
UserPersistentStoreFactory.instance().set(newID, forKey: Constants.DeviceIdKey)
8080
return newID
8181
}
8282

@@ -88,13 +88,13 @@ extension RemoteFeatureFlagStore {
8888
get {
8989
// Read from the cache in a thread-safe way
9090
queue.sync {
91-
UserDefaults.standard.dictionary(forKey: Constants.CachedFlagsKey) as? [String: Bool] ?? [:]
91+
UserPersistentStoreFactory.instance().dictionary(forKey: Constants.CachedFlagsKey) as? [String: Bool] ?? [:]
9292
}
9393
}
9494
set {
9595
// Write to the cache in a thread-safe way.
9696
self.queue.sync {
97-
UserDefaults.standard.set(newValue, forKey: Constants.CachedFlagsKey)
97+
UserPersistentStoreFactory.instance().set(newValue, forKey: Constants.CachedFlagsKey)
9898
}
9999
}
100100
}

WordPress/Classes/Stores/StatsInsightsStore.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ private extension StatsInsightsStore {
890890
}
891891

892892
func lastRefreshDate(for siteID: NSNumber) -> Date? {
893-
if let date = UserDefaults.standard.object(forKey: "\(CacheUserDefaultsKeys.lastRefreshDatePrefix)\(siteID)") as? Date {
893+
if let date = UserPersistentStoreFactory.instance().object(forKey: "\(CacheUserDefaultsKeys.lastRefreshDatePrefix)\(siteID)") as? Date {
894894
return date
895895
}
896896

@@ -902,7 +902,7 @@ private extension StatsInsightsStore {
902902
return
903903
}
904904

905-
UserDefaults.standard.set(date, forKey: "\(CacheUserDefaultsKeys.lastRefreshDatePrefix)\(siteID)")
905+
UserPersistentStoreFactory.instance().set(date, forKey: "\(CacheUserDefaultsKeys.lastRefreshDatePrefix)\(siteID)")
906906
}
907907

908908
private enum CacheUserDefaultsKeys {

WordPress/Classes/Stores/UserPersistentRepository.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ protocol UserPersistentRepositoryReader {
77
func double(forKey key: String) -> Double
88
func array(forKey key: String) -> [Any]?
99
func dictionary(forKey key: String) -> [String: Any]?
10+
func url(forKey key: String) -> URL?
1011
}
1112

1213
protocol UserPersistentRepositoryWriter {
@@ -21,4 +22,16 @@ protocol UserPersistentRepositoryWriter {
2122

2223
typealias UserPersistentRepository = UserPersistentRepositoryReader & UserPersistentRepositoryWriter
2324

24-
extension UserDefaults: UserPersistentRepository { }
25+
extension UserDefaults: UserPersistentRepository {
26+
private static var isOneOffMigrationCompleteKey: String {
27+
"defaults_one_off_migration"
28+
}
29+
30+
var isOneOffMigrationComplete: Bool {
31+
get {
32+
bool(forKey: Self.isOneOffMigrationCompleteKey)
33+
} set {
34+
set(newValue, forKey: Self.isOneOffMigrationCompleteKey)
35+
}
36+
}
37+
}

WordPress/Classes/Stores/UserPersistentStore.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ class UserPersistentStore: UserPersistentRepository {
7777
return UserDefaults.standard.dictionary(forKey: key)
7878
}
7979

80+
func url(forKey key: String) -> URL? {
81+
if let url = userDefaults.url(forKey: key) {
82+
return url
83+
}
84+
85+
return UserDefaults.standard.url(forKey: key)
86+
}
87+
8088
// MARK: - UserPersistentRepositoryWriter
8189
func set(_ value: Any?, forKey key: String) {
8290
userDefaults.set(value, forKey: key)

WordPress/Classes/System/WordPressAppDelegate.swift

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,20 @@ class WordPressAppDelegate: UIResponder, UIApplicationDelegate {
154154
startObservingAppleIDCredentialRevoked()
155155

156156
NotificationCenter.default.post(name: .applicationLaunchCompleted, object: nil)
157+
158+
copyToSharedDefaultsIfNeeded()
157159
return true
158160
}
159161

162+
private func copyToSharedDefaultsIfNeeded() {
163+
if !AppConfiguration.isJetpack && FeatureFlag.sharedUserDefaults.enabled && !UserDefaults.standard.isOneOffMigrationComplete {
164+
let dict = UserDefaults.standard.dictionaryRepresentation()
165+
for (key, value) in dict {
166+
UserPersistentStore.standard.set(value, forKey: key)
167+
UserDefaults.standard.isOneOffMigrationComplete = true
168+
}
169+
}
170+
}
160171

161172
func applicationWillTerminate(_ application: UIApplication) {
162173
DDLogInfo("\(self) \(#function)")
@@ -512,7 +523,7 @@ extension WordPressAppDelegate {
512523
}
513524

514525
@objc func configureWordPressComApi() {
515-
if let baseUrl = UserDefaults.standard.string(forKey: "wpcom-api-base-url") {
526+
if let baseUrl = UserPersistentStoreFactory.instance().string(forKey: "wpcom-api-base-url") {
516527
Environment.replaceEnvironment(wordPressComApiBase: baseUrl)
517528
}
518529
}
@@ -646,9 +657,9 @@ extension WordPressAppDelegate {
646657
let unknown = "Unknown"
647658

648659
let device = UIDevice.current
649-
let crashCount = UserDefaults.standard.integer(forKey: "crashCount")
660+
let crashCount = UserPersistentStoreFactory.instance().integer(forKey: "crashCount")
650661

651-
let extraDebug = UserDefaults.standard.bool(forKey: "extra_debug")
662+
let extraDebug = UserPersistentStoreFactory.instance().bool(forKey: "extra_debug")
652663

653664
let bundle = Bundle.main
654665
let detailedVersionNumber = bundle.detailedVersionNumber() ?? unknown
@@ -668,7 +679,7 @@ extension WordPressAppDelegate {
668679

669680
let devicePlatform = UIDeviceHardware.platformString()
670681
let architecture = UIDeviceHardware.platform()
671-
let languages = UserDefaults.standard.array(forKey: "AppleLanguages")
682+
let languages = UserPersistentStoreFactory.instance().array(forKey: "AppleLanguages")
672683
let currentLanguage = languages?.first ?? unknown
673684
let udid = device.wordPressIdentifier() ?? unknown
674685

@@ -687,25 +698,25 @@ extension WordPressAppDelegate {
687698
if !AccountHelper.isLoggedIn {
688699
// When there are no blogs in the app the settings screen is unavailable.
689700
// In this case, enable extra_debugging by default to help troubleshoot any issues.
690-
guard UserDefaults.standard.object(forKey: "orig_extra_debug") == nil else {
701+
guard UserPersistentStoreFactory.instance().object(forKey: "orig_extra_debug") == nil else {
691702
// Already saved. Don't save again or we could loose the original value.
692703
return
693704
}
694705

695-
let origExtraDebug = UserDefaults.standard.bool(forKey: "extra_debug") ? "YES" : "NO"
696-
UserDefaults.standard.set(origExtraDebug, forKey: "orig_extra_debug")
697-
UserDefaults.standard.set(true, forKey: "extra_debug")
706+
let origExtraDebug = UserPersistentStoreFactory.instance().bool(forKey: "extra_debug") ? "YES" : "NO"
707+
UserPersistentStoreFactory.instance().set(origExtraDebug, forKey: "orig_extra_debug")
708+
UserPersistentStoreFactory.instance().set(true, forKey: "extra_debug")
698709
WordPressAppDelegate.setLogLevel(.verbose)
699710
} else {
700-
guard let origExtraDebug = UserDefaults.standard.string(forKey: "orig_extra_debug") else {
711+
guard let origExtraDebug = UserPersistentStoreFactory.instance().string(forKey: "orig_extra_debug") else {
701712
return
702713
}
703714

704715
let origExtraDebugValue = (origExtraDebug as NSString).boolValue
705716

706717
// Restore the original setting and remove orig_extra_debug
707-
UserDefaults.standard.set(origExtraDebugValue, forKey: "extra_debug")
708-
UserDefaults.standard.removeObject(forKey: "orig_extra_debug")
718+
UserPersistentStoreFactory.instance().set(origExtraDebugValue, forKey: "extra_debug")
719+
UserPersistentStoreFactory.instance().removeObject(forKey: "orig_extra_debug")
709720

710721
if origExtraDebugValue {
711722
WordPressAppDelegate.setLogLevel(.verbose)

WordPress/Classes/Utility/AppAppearance.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ struct AppAppearance {
4646
///
4747
private static var savedStyle: UIUserInterfaceStyle {
4848
get {
49-
guard let rawValue = UserDefaults.standard.value(forKey: Keys.appAppearanceDefaultsKey) as? Int,
49+
guard let rawValue = UserPersistentStoreFactory.instance().object(forKey: Keys.appAppearanceDefaultsKey) as? Int,
5050
let style = UIUserInterfaceStyle(rawValue: rawValue) else {
5151
return AppAppearance.default
5252
}
5353

5454
return style
5555
}
5656
set {
57-
UserDefaults.standard.set(newValue.rawValue, forKey: Keys.appAppearanceDefaultsKey)
57+
UserPersistentStoreFactory.instance().set(newValue.rawValue, forKey: Keys.appAppearanceDefaultsKey)
5858
}
5959
}
6060

WordPress/Classes/Utility/BackgroundTasks/WeeklyRoundupBackgroundTask.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,11 @@ class WeeklyRoundupBackgroundTask: BackgroundTask {
218218
private let lastRunDateKey = "weeklyRoundup.lastExecutionDate"
219219

220220
func getLastRunDate() -> Date? {
221-
UserDefaults.standard.object(forKey: lastRunDateKey) as? Date
221+
UserPersistentStoreFactory.instance().object(forKey: lastRunDateKey) as? Date
222222
}
223223

224224
func setLastRunDate(_ date: Date) {
225-
UserDefaults.standard.set(date, forKey: lastRunDateKey)
225+
UserPersistentStoreFactory.instance().set(date, forKey: lastRunDateKey)
226226
}
227227
}
228228

WordPress/Classes/Utility/ContentCoordinator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ struct DefaultContentCoordinator: ContentCoordinator {
8282
let timePeriod = action.timePeriod {
8383
// Initializing a StatsPeriodType to ensure we have a valid period
8484
let key = SiteStatsDashboardViewController.lastSelectedStatsPeriodTypeKey(forSiteID: siteID)
85-
UserDefaults.standard.set(timePeriod.rawValue, forKey: key)
85+
UserPersistentStoreFactory.instance().set(timePeriod.rawValue, forKey: key)
8686
}
8787
}
8888

0 commit comments

Comments
 (0)