Skip to content

Commit 18ed33a

Browse files
committed
cleaning up PushNotification manager Interface
1 parent 3e5d73b commit 18ed33a

4 files changed

Lines changed: 67 additions & 122 deletions

File tree

libs/SalesforceSDKCore/SalesforceSDKCore/Classes/PushNotification/PushNotificationManager.swift

Lines changed: 56 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -79,45 +79,33 @@ public class PushNotificationManager: NSObject {
7979

8080
var isSimulator: Bool = false
8181
private let notificationRegister: RemoteNotificationRegistering
82-
private var apiVersion: String
8382
private var restClient: RestClient?
84-
private var currentUser: UserAccount?
8583
private var preferences: SFPreferences?
8684

8785
/// Convenience initializer that sets up the PushNotificationManager with default values:
8886
/// - notificationRegister: DefaultRemoteNotificationRegistrar() - Handles APNS registration
89-
/// - apiVersion: RestClient.shared.apiVersion - Uses the current API version from RestClient
9087
/// - restClient: RestClient.shared - Uses the shared RestClient instance
91-
/// - currentUser: UserAccountManager.shared.currentUserAccount - Uses the current logged-in user
9288
/// - preferences: SFPreferences.sharedPreferences(for: .user, user: currentUser) - Uses user-level preferences
9389
@objc
9490
public override convenience init() {
9591
self.init(notificationRegister: DefaultRemoteNotificationRegistrar(),
96-
apiVersion: RestClient.shared.apiVersion,
9792
restClient: RestClient.shared,
98-
currentUser: UserAccountManager.shared.currentUserAccount,
9993
preferences: SFPreferences.sharedPreferences(for: .user, user: UserAccountManager.shared.currentUserAccount))
10094
}
10195

10296
/// Internal initializer used for testing and dependency injection.
10397
/// This initializer allows for customizing the dependencies of PushNotificationManager:
10498
/// - Parameter notificationRegister: The registrar that handles APNS registration. Defaults to DefaultRemoteNotificationRegistrar.
105-
/// - Parameter apiVersion: The Salesforce API version to use. Defaults to RestClient.shared.apiVersion.
10699
/// - Parameter restClient: The REST client for making API calls. Defaults to RestClient.shared.
107-
/// - Parameter currentUser: The user account to use. Defaults to UserAccountManager.shared.currentUserAccount.
108100
/// - Parameter preferences: The preferences store to use. Defaults to user-level SFPreferences.
109101
internal init(notificationRegister: RemoteNotificationRegistering = DefaultRemoteNotificationRegistrar(),
110-
apiVersion: String = RestClient.shared.apiVersion,
111102
restClient : RestClient? = RestClient.shared,
112-
currentUser: UserAccount? = UserAccountManager.shared.currentUserAccount,
113103
preferences: SFPreferences? = nil) {
114104
self.notificationRegister = notificationRegister
115-
self.apiVersion = apiVersion
116105
self.restClient = restClient
117-
self.currentUser = currentUser
118106

119107
if preferences == nil {
120-
self.preferences = SFPreferences.sharedPreferences(for: .user, user: currentUser)
108+
self.preferences = SFPreferences.currentUserLevel()
121109
} else {
122110
self.preferences = preferences
123111
}
@@ -130,9 +118,8 @@ public class PushNotificationManager: NSObject {
130118
self.isSimulator = false
131119
#endif
132120

133-
let prefs = SFPreferences.currentUserLevel()
134-
self.deviceToken = prefs?.string(forKey: PushNotificationConstants.deviceToken)
135-
self.deviceSalesforceId = prefs?.string(forKey: PushNotificationConstants.deviceSalesforceId)
121+
self.deviceToken = preferences?.string(forKey: PushNotificationConstants.deviceToken)
122+
self.deviceSalesforceId = preferences?.string(forKey: PushNotificationConstants.deviceSalesforceId)
136123

137124
NotificationCenter.default.addObserver(self,
138125
selector: #selector(onUserLoggedIn(_:)),
@@ -224,6 +211,7 @@ public class PushNotificationManager: NSObject {
224211
return false
225212
}
226213

214+
let apiVersion = restClient?.apiVersion ?? SFRestDefaultAPIVersion
227215
let path = "/\(apiVersion)/\(PushNotificationConstants.endPoint)"
228216
let request = RestRequest(method: .POST, path: path, queryParams: nil)
229217

@@ -286,7 +274,7 @@ public class PushNotificationManager: NSObject {
286274

287275
Task {
288276
do {
289-
try await self.fetchAndStoreNotificationTypes(restClient: restClient, account: user)
277+
try await self.fetchAndStoreNotificationTypes(restClient: restClient)
290278
} catch {
291279
SFSDKCoreLogger.e(Self.self, message: "Get Notification Types Error: \(error.localizedDescription)")
292280
}
@@ -317,64 +305,14 @@ public class PushNotificationManager: NSObject {
317305
return unregisterSalesforceNotifications(for: user, completionBlock: completionBlock)
318306
}
319307

320-
/// Unregisters the device from Salesforce push notifications for a specific user.
321-
///
322-
/// - Parameters:
323-
/// - user: The user account to unregister.
324-
/// - completionBlock: A block executed when unregistration is complete.
325-
/// - Returns: `true` if unregistration started successfully, otherwise `false`.
326-
@discardableResult
327-
@objc(unregisterSalesforceNotificationsWithCompletionBlock:completionBlock:)
328-
public func unregisterSalesforceNotifications(for user: UserAccount,
329-
completionBlock: (() -> Void)?) -> Bool {
330-
guard deviceSalesforceId != nil else {
331-
completionBlock?()
332-
return true
333-
}
334-
335-
if isSimulator {
336-
completionBlock?()
337-
return true
338-
}
339-
340-
guard let prefs = preferences else {
341-
SFSDKCoreLogger.e(Self.self, message: "Cannot unregister from notifications with Salesforce: no user prefs")
342-
return false
343-
}
344-
345-
guard let sfId = prefs.string(forKey: PushNotificationConstants.deviceSalesforceId) else {
346-
SFSDKCoreLogger.e(Self.self, message: "Cannot unregister from notifications with Salesforce: no deviceSalesforceId")
347-
return false
348-
}
349-
350-
let path = "/\(apiVersion)/\(PushNotificationConstants.endPoint)/\(sfId)"
351-
let request = RestRequest(method: .DELETE,
352-
path: path,
353-
queryParams: nil)
354-
Task {
355-
do {
356-
_ = try await restClient?.send(request: request)
357-
completionBlock?()
358-
} catch {
359-
SFSDKCoreLogger.e(Self.self, message: "Push notification unregistration failed: \(error.localizedDescription)")
360-
completionBlock?()
361-
}
362-
}
363-
364-
SFSDKCoreLogger.i(Self.self, message: "Unregister from notifications with Salesforce sent")
365-
return true
366-
}
367-
368308
/// Fetches and stores actionable notification types from the server or cache.
369309
///
370310
/// - Parameters:
371311
/// - restClient: The `RestClient` to use for the API call.
372-
/// - account: The user account to associate notification types with.
373312
/// - Throws: An error if the types cannot be retrieved from server or cache.
374-
@objc(fetchAndStoreNotificationTypesWithRestClient:account:completionHandler:)
375-
public func fetchAndStoreNotificationTypes(restClient: RestClient = RestClient.shared,
376-
account: UserAccount? = UserAccountManager.shared.currentUserAccount) async throws {
377-
guard let account = account else {
313+
@objc(fetchAndStoreNotificationTypesWithRestClient:completionHandler:)
314+
public func fetchAndStoreNotificationTypes(restClient: RestClient = RestClient.shared) async throws {
315+
guard let account = UserAccountManager.shared.currentUserAccount else {
378316
throw PushNotificationManagerError.currentUserNotDetected
379317
}
380318

@@ -439,25 +377,10 @@ public class PushNotificationManager: NSObject {
439377
}
440378
self.unregisterForSalesforceNotifications(user: currentUser, completionBlock)
441379
}
442-
443-
/// Unregister from Salesforce notfications for a specific user
444-
/// - Parameters:
445-
/// - user: The user that should be unregistered from notfications
446-
/// - completionBlock: completion block to call with success or failure
447-
public func unregisterForSalesforceNotifications(user: UserAccount, _ completionBlock:@escaping (Bool)->()) {
448-
let result = unregisterSalesforceNotifications(for: user) {
449-
completionBlock(true)
450-
}
451-
452-
if (!result) {
453-
completionBlock(false)
454-
}
455-
}
456380
}
457381

458382
private extension PushNotificationManager {
459383
@objc private func onUserLoggedIn(_ notification: Notification) {
460-
refreshDependencies()
461384

462385
if deviceToken != nil {
463386
SFSDKCoreLogger.i(Self.self, message: "User logged in, registering push")
@@ -476,13 +399,54 @@ private extension PushNotificationManager {
476399
_ = registerSalesforceNotifications(completionBlock: nil, failBlock: nil)
477400
}
478401

479-
func refreshDependencies() {
480-
// Refresh dependencies now that user is logged in
481-
let restClient = RestClient.shared
482-
let user = UserAccountManager.shared.currentUserAccount
402+
private func unregisterSalesforceNotifications(for user: UserAccount,
403+
completionBlock: (() -> Void)?) -> Bool {
404+
guard deviceSalesforceId != nil else {
405+
completionBlock?()
406+
return true
407+
}
483408

484-
self.restClient = restClient
485-
self.apiVersion = restClient.apiVersion
486-
self.currentUser = user
409+
if isSimulator {
410+
completionBlock?()
411+
return true
412+
}
413+
414+
guard let prefs = preferences else {
415+
SFSDKCoreLogger.e(Self.self, message: "Cannot unregister from notifications with Salesforce: no user prefs")
416+
return false
417+
}
418+
419+
guard let sfId = prefs.string(forKey: PushNotificationConstants.deviceSalesforceId) else {
420+
SFSDKCoreLogger.e(Self.self, message: "Cannot unregister from notifications with Salesforce: no deviceSalesforceId")
421+
return false
422+
}
423+
424+
let apiVersion = restClient?.apiVersion ?? SFRestDefaultAPIVersion
425+
let path = "/\(apiVersion)/\(PushNotificationConstants.endPoint)/\(sfId)"
426+
let request = RestRequest(method: .DELETE,
427+
path: path,
428+
queryParams: nil)
429+
Task {
430+
do {
431+
_ = try await restClient?.send(request: request)
432+
completionBlock?()
433+
} catch {
434+
SFSDKCoreLogger.e(Self.self, message: "Push notification unregistration failed: \(error.localizedDescription)")
435+
completionBlock?()
436+
}
437+
}
438+
439+
SFSDKCoreLogger.i(Self.self, message: "Unregister from notifications with Salesforce sent")
440+
return true
441+
}
442+
443+
private func unregisterForSalesforceNotifications(user: UserAccount, _ completionBlock:@escaping (Bool)->()) {
444+
let result = unregisterSalesforceNotifications(for: user) {
445+
completionBlock(true)
446+
}
447+
448+
if (!result) {
449+
completionBlock(false)
450+
}
487451
}
488452
}

libs/SalesforceSDKCore/SalesforceSDKCore/Classes/UserAccount/SFUserAccountManager.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ - (void)logoutUser:(SFUserAccount *)user reason:(SFLogoutReason)reason {
670670

671671
// Before starting actual logout (which will tear down SFRestAPI), first unregister from push notifications if needed
672672
__weak typeof(self) weakSelf = self;
673-
[[SFPushNotificationManager sharedInstance] unregisterSalesforceNotificationsWithCompletionBlock:user completionBlock:^void() {
673+
[[SFPushNotificationManager sharedInstance] unregisterSalesforceNotificationsWithCompletionBlock:^void() {
674674
__strong typeof(weakSelf) strongSelf = weakSelf;
675675
[strongSelf postPushUnregistration:user logoutReason:reason];
676676
}];

libs/SalesforceSDKCore/SalesforceSDKCoreTests/PushNotificationManagerTests.swift

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ class PushNotificationManagerTests: XCTestCase {
1717
mockRestClient = MockRestClient()
1818
mockRestClient.apiVersion = SFRestDefaultAPIVersion
1919
mockUserAccount = UserAccount()
20+
UserAccountManager.shared.currentUserAccount = mockUserAccount
2021
mockPreferences = MockPreferences()
2122
mockPreferences.setObject("mock-sfid", forKey: PushNotificationConstants.deviceSalesforceId)
2223
pushNotificationManager = PushNotificationManager(notificationRegister: mockApplicationHelper,
23-
apiVersion: SFRestDefaultAPIVersion,
2424
restClient: mockRestClient,
25-
currentUser: mockUserAccount,
2625
preferences: mockPreferences)
2726
pushNotificationManager.isSimulator = false
2827
}
@@ -533,10 +532,7 @@ class PushNotificationManagerTests: XCTestCase {
533532
mockRestClient.jsonResponse = makeMockJSONResponse()
534533

535534
// When
536-
try await pushNotificationManager.fetchAndStoreNotificationTypes(
537-
restClient: mockRestClient,
538-
account: mockUserAccount
539-
)
535+
try await pushNotificationManager.fetchAndStoreNotificationTypes(restClient: mockRestClient)
540536

541537
// Then
542538
XCTAssertNotNil(mockUserAccount.notificationTypes)
@@ -546,14 +542,11 @@ class PushNotificationManagerTests: XCTestCase {
546542

547543
func testFetchAndStoreNotificationTypes_NoAccount() async {
548544
// Given
549-
let nilAccount: UserAccount? = nil
545+
UserAccountManager.shared.currentUserAccount = nil
550546

551547
// When/Then
552548
do {
553-
try await pushNotificationManager.fetchAndStoreNotificationTypes(
554-
restClient: mockRestClient,
555-
account: nilAccount
556-
)
549+
try await pushNotificationManager.fetchAndStoreNotificationTypes(restClient: mockRestClient)
557550
XCTFail("Expected currentUserNotDetected error")
558551
} catch let error as PushNotificationManagerError {
559552
XCTAssertEqual(error, .currentUserNotDetected)
@@ -568,10 +561,7 @@ class PushNotificationManagerTests: XCTestCase {
568561

569562
// When/Then
570563
do {
571-
try await pushNotificationManager.fetchAndStoreNotificationTypes(
572-
restClient: mockRestClient,
573-
account: mockUserAccount
574-
)
564+
try await pushNotificationManager.fetchAndStoreNotificationTypes(restClient: mockRestClient)
575565
XCTFail("Expected notificationActionInvocationFailed error")
576566
} catch let error as PushNotificationManagerError {
577567
XCTAssertEqual(error, .failedNotificationTypesRetrieval)
@@ -592,10 +582,7 @@ class PushNotificationManagerTests: XCTestCase {
592582
mockUserAccount.notificationTypes = cachedTypes
593583

594584
// When
595-
try await pushNotificationManager.fetchAndStoreNotificationTypes(
596-
restClient: mockRestClient,
597-
account: mockUserAccount
598-
)
585+
try await pushNotificationManager.fetchAndStoreNotificationTypes(restClient: mockRestClient)
599586

600587
// Then
601588
XCTAssertNotNil(mockUserAccount.notificationTypes)
@@ -611,10 +598,7 @@ class PushNotificationManagerTests: XCTestCase {
611598

612599
// When/Then
613600
do {
614-
try await pushNotificationManager.fetchAndStoreNotificationTypes(
615-
restClient: mockRestClient,
616-
account: mockUserAccount
617-
)
601+
try await pushNotificationManager.fetchAndStoreNotificationTypes(restClient: mockRestClient)
618602
XCTFail("Expected failedNotificationTypesRetrieval error")
619603
} catch let error as PushNotificationManagerError {
620604
XCTAssertEqual(error, .failedNotificationTypesRetrieval)
@@ -635,10 +619,7 @@ class PushNotificationManagerTests: XCTestCase {
635619
mockUserAccount.notificationTypes = cachedTypes
636620

637621
// When
638-
try await pushNotificationManager.fetchAndStoreNotificationTypes(
639-
restClient: mockRestClient,
640-
account: mockUserAccount
641-
)
622+
try await pushNotificationManager.fetchAndStoreNotificationTypes(restClient: mockRestClient)
642623

643624
// Then
644625
XCTAssertNotNil(mockUserAccount.notificationTypes)

libs/SalesforceSDKCore/SalesforceSDKCoreTests/SFPushNotificationManagerTests.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,14 @@ - (void)testRegisterSalesforceNotifications_NoDeviceIdPref {
8282

8383
- (void)testUnregisterSalesforceNotifications_NoUserCredentials {
8484
self.user.credentials = (SFOAuthCredentials* _Nonnull)nil;
85-
BOOL result = [self.manager unregisterSalesforceNotificationsWithCompletionBlock:self.user completionBlock:nil];
85+
BOOL result = [self.manager unregisterSalesforceNotificationsWithCompletionBlock:nil];
8686
XCTAssertFalse(result);
8787
}
8888

8989
- (void)testUnregisterSalesforceNotifications_NoDeviceIdPref {
9090
SFPreferences *pref = [SFPreferences sharedPreferencesForScope:SFUserAccountScopeUser user:self.user];
9191
[pref removeObjectForKey:kSFDeviceSalesforceId];
92-
BOOL result = [self.manager unregisterSalesforceNotificationsWithCompletionBlock:self.user completionBlock:nil];
92+
BOOL result = [self.manager unregisterSalesforceNotificationsWithCompletionBlock:nil];
9393
XCTAssertFalse(result);
9494
}
9595

0 commit comments

Comments
 (0)