Skip to content

Commit 69642e3

Browse files
authored
Merge pull request #19236 from wordpress-mobile/task/jp-shared-defaults-utility-variables
[Jetpack] Shared Defaults Utility Variables
2 parents b3f9671 + e3fe6ba commit 69642e3

30 files changed

Lines changed: 245 additions & 324 deletions

WordPress/Classes/Stores/UserPersistentRepository.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
protocol UserPersistentRepositoryReader {
2-
func object(forKey key: String) -> Any?
32
func string(forKey key: String) -> String?
43
func bool(forKey key: String) -> Bool
54
func integer(forKey key: String) -> Int
@@ -10,7 +9,7 @@ protocol UserPersistentRepositoryReader {
109
func url(forKey key: String) -> URL?
1110
}
1211

13-
protocol UserPersistentRepositoryWriter {
12+
protocol UserPersistentRepositoryWriter: KeyValueDatabase {
1413
func set(_ value: Any?, forKey key: String)
1514
func set(_ value: Int, forKey key: String)
1615
func set(_ value: Float, forKey key: String)
@@ -20,9 +19,11 @@ protocol UserPersistentRepositoryWriter {
2019
func removeObject(forKey key: String)
2120
}
2221

23-
typealias UserPersistentRepository = UserPersistentRepositoryReader & UserPersistentRepositoryWriter
22+
typealias UserPersistentRepository = UserPersistentRepositoryReader & UserPersistentRepositoryWriter & UserPersistentRepositoryUtility
2423

25-
extension UserDefaults: UserPersistentRepository {
24+
extension UserDefaults: UserPersistentRepository {}
25+
26+
extension UserPersistentStore {
2627
private static var isOneOffMigrationCompleteKey: String {
2728
"defaults_one_off_migration"
2829
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import Foundation
2+
3+
private enum UPRUConstants {
4+
static let promptKey = "onboarding_notifications_prompt_displayed"
5+
static let questionKey = "onboarding_question_selection"
6+
static let notificationPrimerAlertWasDisplayed = "NotificationPrimerAlertWasDisplayed"
7+
static let notificationsTabAccessCount = "NotificationsTabAccessCount"
8+
static let notificationPrimerInlineWasAcknowledged = "notificationPrimerInlineWasAcknowledged"
9+
static let secondNotificationsAlertCount = "secondNotificationsAlertCount"
10+
static let hasShownCustomAppIconUpgradeAlert = "custom-app-icon-upgrade-alert-shown"
11+
static let createButtonTooltipWasDisplayed = "CreateButtonTooltipWasDisplayed"
12+
static let createButtonTooltipDisplayCount = "CreateButtonTooltipDisplayCount"
13+
static let savedPostsPromoWasDisplayed = "SavedPostsV1PromoWasDisplayed"
14+
static let storiesIntroWasAcknowledged = "storiesIntroWasAcknowledged"
15+
static let currentAnnouncementsKey = "currentAnnouncements"
16+
static let currentAnnouncementsDateKey = "currentAnnouncementsDate"
17+
static let announcementsVersionDisplayedKey = "announcementsVersionDisplayed"
18+
}
19+
20+
protocol UserPersistentRepositoryUtility: AnyObject {
21+
var onboardingNotificationsPromptDisplayed: Bool { get set }
22+
var onboardingQuestionSelected: OnboardingOption? { get set }
23+
var notificationPrimerAlertWasDisplayed: Bool { get set }
24+
}
25+
26+
extension UserPersistentRepositoryUtility {
27+
var onboardingNotificationsPromptDisplayed: Bool {
28+
get {
29+
UserPersistentStoreFactory.instance().bool(forKey: UPRUConstants.promptKey)
30+
}
31+
set {
32+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.promptKey)
33+
}
34+
}
35+
36+
var onboardingQuestionSelected: OnboardingOption? {
37+
get {
38+
if let str = UserPersistentStoreFactory.instance().string(forKey: UPRUConstants.questionKey) {
39+
return OnboardingOption(rawValue: str)
40+
}
41+
42+
return nil
43+
}
44+
set {
45+
UserPersistentStoreFactory.instance().set(newValue?.rawValue, forKey: UPRUConstants.questionKey)
46+
}
47+
}
48+
49+
var notificationPrimerAlertWasDisplayed: Bool {
50+
get {
51+
UserPersistentStoreFactory.instance().bool(forKey: UPRUConstants.notificationPrimerAlertWasDisplayed)
52+
}
53+
set {
54+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.notificationPrimerAlertWasDisplayed)
55+
}
56+
}
57+
58+
var notificationsTabAccessCount: Int {
59+
get {
60+
UserPersistentStoreFactory.instance().integer(forKey: UPRUConstants.notificationsTabAccessCount)
61+
}
62+
63+
set {
64+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.notificationsTabAccessCount)
65+
}
66+
}
67+
68+
var welcomeNotificationSeenKey: String {
69+
return "welcomeNotificationSeen"
70+
}
71+
72+
var notificationPrimerInlineWasAcknowledged: Bool {
73+
get {
74+
UserPersistentStoreFactory.instance().bool(forKey: UPRUConstants.notificationPrimerInlineWasAcknowledged)
75+
}
76+
set {
77+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.notificationPrimerInlineWasAcknowledged)
78+
}
79+
}
80+
81+
var secondNotificationsAlertCount: Int {
82+
get {
83+
UserPersistentStoreFactory.instance().integer(forKey: UPRUConstants.secondNotificationsAlertCount)
84+
}
85+
set {
86+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.secondNotificationsAlertCount)
87+
}
88+
}
89+
90+
var hasShownCustomAppIconUpgradeAlert: Bool {
91+
get {
92+
UserPersistentStoreFactory.instance().bool(forKey: UPRUConstants.hasShownCustomAppIconUpgradeAlert)
93+
}
94+
set {
95+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.hasShownCustomAppIconUpgradeAlert)
96+
}
97+
}
98+
99+
var createButtonTooltipDisplayCount: Int {
100+
get {
101+
UserPersistentStoreFactory.instance().integer(forKey: UPRUConstants.createButtonTooltipDisplayCount)
102+
}
103+
set {
104+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.createButtonTooltipDisplayCount)
105+
}
106+
}
107+
108+
var createButtonTooltipWasDisplayed: Bool {
109+
get {
110+
UserPersistentStoreFactory.instance().bool(forKey: UPRUConstants.createButtonTooltipWasDisplayed)
111+
}
112+
set {
113+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.createButtonTooltipWasDisplayed)
114+
}
115+
}
116+
117+
var savedPostsPromoWasDisplayed: Bool {
118+
get {
119+
return UserPersistentStoreFactory.instance().bool(forKey: UPRUConstants.savedPostsPromoWasDisplayed)
120+
}
121+
set {
122+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.savedPostsPromoWasDisplayed)
123+
}
124+
}
125+
126+
var storiesIntroWasAcknowledged: Bool {
127+
get {
128+
return UserPersistentStoreFactory.instance().bool(forKey: UPRUConstants.storiesIntroWasAcknowledged)
129+
}
130+
set {
131+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.storiesIntroWasAcknowledged)
132+
}
133+
}
134+
135+
var announcements: [Announcement]? {
136+
get {
137+
guard let encodedAnnouncements = UserPersistentStoreFactory.instance().object(forKey: UPRUConstants.currentAnnouncementsKey) as? Data,
138+
let announcements = try? PropertyListDecoder().decode([Announcement].self, from: encodedAnnouncements) else {
139+
return nil
140+
}
141+
return announcements
142+
}
143+
144+
set {
145+
guard let announcements = newValue, let encodedAnnouncements = try? PropertyListEncoder().encode(announcements) else {
146+
UserPersistentStoreFactory.instance().removeObject(forKey: UPRUConstants.currentAnnouncementsKey)
147+
UserPersistentStoreFactory.instance().removeObject(forKey: UPRUConstants.currentAnnouncementsDateKey)
148+
return
149+
}
150+
UserPersistentStoreFactory.instance().set(encodedAnnouncements, forKey: UPRUConstants.currentAnnouncementsKey)
151+
UserPersistentStoreFactory.instance().set(Date(), forKey: UPRUConstants.currentAnnouncementsDateKey)
152+
}
153+
}
154+
155+
var announcementsDate: Date? {
156+
UserPersistentStoreFactory.instance().object(forKey: UPRUConstants.currentAnnouncementsDateKey) as? Date
157+
}
158+
159+
var announcementsVersionDisplayed: String? {
160+
get {
161+
UserPersistentStoreFactory.instance().string(forKey: UPRUConstants.announcementsVersionDisplayedKey)
162+
}
163+
set {
164+
UserPersistentStoreFactory.instance().set(newValue, forKey: UPRUConstants.announcementsVersionDisplayedKey)
165+
}
166+
}
167+
}

WordPress/Classes/System/WordPressAppDelegate.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,12 @@ class WordPressAppDelegate: UIResponder, UIApplicationDelegate {
160160
}
161161

162162
private func copyToSharedDefaultsIfNeeded() {
163-
if !AppConfiguration.isJetpack && FeatureFlag.sharedUserDefaults.enabled && !UserDefaults.standard.isOneOffMigrationComplete {
163+
if !AppConfiguration.isJetpack && FeatureFlag.sharedUserDefaults.enabled && !UserPersistentStore.standard.isOneOffMigrationComplete {
164164
let dict = UserDefaults.standard.dictionaryRepresentation()
165165
for (key, value) in dict {
166166
UserPersistentStore.standard.set(value, forKey: key)
167-
UserDefaults.standard.isOneOffMigrationComplete = true
168167
}
168+
UserPersistentStore.standard.isOneOffMigrationComplete = true
169169
}
170170
}
171171

@@ -227,7 +227,7 @@ class WordPressAppDelegate: UIResponder, UIApplicationDelegate {
227227

228228
func application(_ application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
229229
let lastSavedStateVersionKey = "lastSavedStateVersionKey"
230-
let defaults = UserDefaults.standard
230+
let defaults = UserPersistentStoreFactory.instance()
231231

232232
var shouldRestoreApplicationState = false
233233

@@ -237,9 +237,8 @@ class WordPressAppDelegate: UIResponder, UIApplicationDelegate {
237237
shouldRestoreApplicationState = self.shouldRestoreApplicationState
238238
}
239239

240-
defaults.setValue(currentVersion, forKey: lastSavedStateVersionKey)
240+
defaults.set(currentVersion, forKey: lastSavedStateVersionKey)
241241
}
242-
243242
return shouldRestoreApplicationState
244243
}
245244

WordPress/Classes/Utility/KeychainUtils.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,13 @@ class KeychainUtils: NSObject {
4343
}
4444

4545
func copyKeychainToSharedKeychainIfNeeded() {
46+
guard let defaults = UserDefaults(suiteName: WPAppGroupName) else {
47+
return
48+
}
49+
4650
guard shouldUseSharedKeychain(),
4751
AppConfiguration.isWordPress,
48-
!UserPersistentStoreFactory.instance().bool(forKey: "keychain-copied"),
52+
!defaults.bool(forKey: "keychain-copied"),
4953
let items = try? keychainUtils.getAllPasswords(forAccessGroup: nil) else {
5054
return
5155
}
@@ -59,7 +63,7 @@ class KeychainUtils: NSObject {
5963

6064
try? keychainUtils.storeUsername(username, andPassword: password, forServiceName: serviceName, accessGroup: WPAppKeychainAccessGroup, updateExisting: false)
6165
}
62-
UserPersistentStoreFactory.instance().set(true, forKey: "keychain-copied")
66+
defaults.set(true, forKey: "keychain-copied")
6367
}
6468

6569
}

WordPress/Classes/Utility/Migrations/20-21/AccountToAccount20to21.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ class AccountToAccount20to21: NSEntityMigrationPolicy {
1818
if let unwrappedAccount = legacyDefaultWordPressAccount(manager.sourceContext) {
1919
let username = unwrappedAccount.value(forKey: "username") as! String
2020

21-
let userDefaults = UserDefaults.standard
22-
userDefaults.setValue(username, forKey: defaultDotcomUsernameKey)
21+
let userDefaults = UserPersistentStoreFactory.instance()
22+
userDefaults.set(username, forKey: defaultDotcomUsernameKey)
2323

2424
DDLogWarn(">> Migration process matched [\(username)] as the default WordPress.com account")
2525
} else {
@@ -29,7 +29,7 @@ class AccountToAccount20to21: NSEntityMigrationPolicy {
2929

3030
override func end(_ mapping: NSEntityMapping, manager: NSMigrationManager) throws {
3131
// Load the default username
32-
let userDefaults = UserDefaults.standard
32+
let userDefaults = UserPersistentStoreFactory.instance()
3333
let defaultUsername = userDefaults.string(forKey: defaultDotcomUsernameKey) ?? String()
3434

3535
// Find the Default Account
@@ -88,7 +88,7 @@ class AccountToAccount20to21: NSEntityMigrationPolicy {
8888

8989
let accountURL = account.objectID.uriRepresentation()
9090

91-
let defaults = UserDefaults.standard
91+
let defaults = UserPersistentStoreFactory.instance()
9292
defaults.set(accountURL, forKey: defaultDotcomKey)
9393
}
9494
}

WordPress/Classes/Utility/Migrations/AccountToAccount22to23.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ class AccountToAccount22to23: NSEntityMigrationPolicy {
3131
}
3232

3333
if isDotCom! == true {
34-
let userDefaults = UserDefaults.standard
35-
userDefaults.setValue(username!, forKey: defaultDotcomUsernameKey)
34+
let userDefaults = UserPersistentStoreFactory.instance()
35+
userDefaults.set(username!, forKey: defaultDotcomUsernameKey)
3636

3737
DDLogWarn(">> Migration process matched [\(username!)] as the default WordPress.com account")
3838
} else {
@@ -74,7 +74,7 @@ class AccountToAccount22to23: NSEntityMigrationPolicy {
7474
}
7575

7676
// Set the defaultAccount (if any)
77-
let userDefaults = UserDefaults.standard
77+
let userDefaults = UserPersistentStoreFactory.instance()
7878

7979
if defaultAccount != nil {
8080
let uuid = defaultAccount!.value(forKey: "uuid") as! String
@@ -142,7 +142,7 @@ class AccountToAccount22to23: NSEntityMigrationPolicy {
142142
return
143143
}
144144

145-
let defaults = UserDefaults.standard
145+
let defaults = UserPersistentStoreFactory.instance()
146146
defaults.set(uuid, forKey: defaultDotcomUUIDKey)
147147
}
148148

WordPress/Classes/ViewRelated/Blog/My Site/MySiteSettings.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ protocol DefaultSectionProvider {
99
///
1010
@objc final class MySiteSettings: NSObject, DefaultSectionProvider {
1111

12-
private var userDefaults: UserDefaults {
13-
UserDefaults.standard
12+
private var userDefaults: UserPersistentRepository {
13+
UserPersistentStoreFactory.instance()
1414
}
1515

1616
var defaultSection: MySiteViewController.Section {

WordPress/Classes/ViewRelated/Blog/Onboarding Questions Prompt/OnboardingQuestionsCoordinator.swift

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extension OnboardingQuestionsCoordinator {
5151
}
5252

5353
track(.onboardingQuestionsItemSelected, option: option)
54-
UserDefaults.standard.onboardingQuestionSelected = option
54+
UserPersistentStoreFactory.instance().onboardingQuestionSelected = option
5555

5656
// Check if notification's are already enabled
5757
// If they are just dismiss, if not then prompt
@@ -73,7 +73,7 @@ extension OnboardingQuestionsCoordinator {
7373
extension OnboardingQuestionsCoordinator {
7474
func notificationsDisplayed(option: OnboardingOption) {
7575
track(.onboardingEnableNotificationsDisplayed, option: option)
76-
UserDefaults.standard.onboardingNotificationsPromptDisplayed = true
76+
UserPersistentStoreFactory.instance().onboardingNotificationsPromptDisplayed = true
7777
}
7878

7979
func notificationsEnabledTapped(selection: OnboardingOption) {
@@ -91,31 +91,3 @@ extension OnboardingQuestionsCoordinator {
9191
dismiss(selection: selection)
9292
}
9393
}
94-
95-
96-
extension UserDefaults {
97-
private static let promptKey = "onboarding_notifications_prompt_displayed"
98-
private static let questionKey = "onboarding_question_selection"
99-
100-
var onboardingNotificationsPromptDisplayed: Bool {
101-
get {
102-
bool(forKey: Self.promptKey)
103-
}
104-
set {
105-
set(newValue, forKey: Self.promptKey)
106-
}
107-
}
108-
109-
var onboardingQuestionSelected: OnboardingOption? {
110-
get {
111-
if let str = string(forKey: Self.questionKey) {
112-
return OnboardingOption(rawValue: str)
113-
}
114-
115-
return nil
116-
}
117-
set {
118-
set(newValue?.rawValue, forKey: Self.questionKey)
119-
}
120-
}
121-
}

0 commit comments

Comments
 (0)