Skip to content

Commit f8b18f6

Browse files
committed
ensure rest client updated on login and logout
1 parent 18ed33a commit f8b18f6

1 file changed

Lines changed: 100 additions & 59 deletions

File tree

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

Lines changed: 100 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ public class PushNotificationManager: NSObject {
8282
private var restClient: RestClient?
8383
private var preferences: SFPreferences?
8484

85+
private var loginObserver: NSObjectProtocol?
86+
private var logoutObserver: NSObjectProtocol?
87+
private var enterForegroundObserver: NSObjectProtocol?
88+
8589
/// Convenience initializer that sets up the PushNotificationManager with default values:
8690
/// - notificationRegister: DefaultRemoteNotificationRegistrar() - Handles APNS registration
8791
/// - restClient: RestClient.shared - Uses the shared RestClient instance
@@ -121,15 +125,14 @@ public class PushNotificationManager: NSObject {
121125
self.deviceToken = preferences?.string(forKey: PushNotificationConstants.deviceToken)
122126
self.deviceSalesforceId = preferences?.string(forKey: PushNotificationConstants.deviceSalesforceId)
123127

124-
NotificationCenter.default.addObserver(self,
125-
selector: #selector(onUserLoggedIn(_:)),
126-
name: NSNotification.Name(rawValue: UserAccountManager.didLogInUser.rawValue),
127-
object: nil)
128-
129-
NotificationCenter.default.addObserver(self,
130-
selector: #selector(onAppWillEnterForeground(_:)),
131-
name: UIApplication.willEnterForegroundNotification,
132-
object: nil)
128+
setupNotificationObservers()
129+
}
130+
131+
deinit {
132+
let center = NotificationCenter.default
133+
center.removeObserver(loginObserver ?? self)
134+
center.removeObserver(logoutObserver ?? self)
135+
center.removeObserver(enterForegroundObserver ?? self)
133136
}
134137

135138
/// Registers the app with Apple Push Notification Service (APNS).
@@ -305,6 +308,55 @@ public class PushNotificationManager: NSObject {
305308
return unregisterSalesforceNotifications(for: user, completionBlock: completionBlock)
306309
}
307310

311+
/// Unregisters the device from Salesforce push notifications for a specific user.
312+
///
313+
/// - Parameters:
314+
/// - user: The user account to unregister.
315+
/// - completionBlock: A block executed when unregistration is complete.
316+
/// - Returns: `true` if unregistration started successfully, otherwise `false`.
317+
@discardableResult
318+
@objc(unregisterSalesforceNotificationsWithCompletionBlock:completionBlock:)
319+
public func unregisterSalesforceNotifications(for user: UserAccount,
320+
completionBlock: (() -> Void)?) -> Bool {
321+
guard deviceSalesforceId != nil else {
322+
completionBlock?()
323+
return true
324+
}
325+
326+
if isSimulator {
327+
completionBlock?()
328+
return true
329+
}
330+
331+
guard let prefs = preferences else {
332+
SFSDKCoreLogger.e(Self.self, message: "Cannot unregister from notifications with Salesforce: no user prefs")
333+
return false
334+
}
335+
336+
guard let sfId = prefs.string(forKey: PushNotificationConstants.deviceSalesforceId) else {
337+
SFSDKCoreLogger.e(Self.self, message: "Cannot unregister from notifications with Salesforce: no deviceSalesforceId")
338+
return false
339+
}
340+
341+
let apiVersion = restClient?.apiVersion ?? SFRestDefaultAPIVersion
342+
let path = "/\(apiVersion)/\(PushNotificationConstants.endPoint)/\(sfId)"
343+
let request = RestRequest(method: .DELETE,
344+
path: path,
345+
queryParams: nil)
346+
Task {
347+
do {
348+
_ = try await restClient?.send(request: request)
349+
completionBlock?()
350+
} catch {
351+
SFSDKCoreLogger.e(Self.self, message: "Push notification unregistration failed: \(error.localizedDescription)")
352+
completionBlock?()
353+
}
354+
}
355+
356+
SFSDKCoreLogger.i(Self.self, message: "Unregister from notifications with Salesforce sent")
357+
return true
358+
}
359+
308360
/// Fetches and stores actionable notification types from the server or cache.
309361
///
310362
/// - Parameters:
@@ -377,11 +429,47 @@ public class PushNotificationManager: NSObject {
377429
}
378430
self.unregisterForSalesforceNotifications(user: currentUser, completionBlock)
379431
}
432+
433+
/// Unregister from Salesforce notfications for a specific user
434+
/// - Parameters:
435+
/// - user: The user that should be unregistered from notfications
436+
/// - completionBlock: completion block to call with success or failure
437+
public func unregisterForSalesforceNotifications(user: UserAccount, _ completionBlock:@escaping (Bool)->()) {
438+
let result = unregisterSalesforceNotifications(for: user) {
439+
completionBlock(true)
440+
}
441+
442+
if (!result) {
443+
completionBlock(false)
444+
}
445+
}
446+
380447
}
381448

382449
private extension PushNotificationManager {
383-
@objc private func onUserLoggedIn(_ notification: Notification) {
450+
451+
private func setupNotificationObservers() {
452+
loginObserver = NotificationCenter.default.addObserver(
453+
forName: UserAccountManager.didLogInUser,
454+
object: nil,
455+
queue: .main
456+
) { [weak self] in self?.onUserLoggedIn($0) }
457+
458+
logoutObserver = NotificationCenter.default.addObserver(
459+
forName: UserAccountManager.didLogoutUser,
460+
object: nil,
461+
queue: .main
462+
) { [weak self] in self?.onUserLoggedOut($0) }
384463

464+
enterForegroundObserver = NotificationCenter.default.addObserver(
465+
forName: UIApplication.willEnterForegroundNotification,
466+
object: nil,
467+
queue: .main
468+
) { [weak self] in self?.onAppWillEnterForeground($0) }
469+
}
470+
471+
@objc private func onUserLoggedIn(_ notification: Notification) {
472+
restClient = RestClient.shared
385473
if deviceToken != nil {
386474
SFSDKCoreLogger.i(Self.self, message: "User logged in, registering push")
387475
_ = registerSalesforceNotifications(completionBlock: nil, failBlock: nil)
@@ -399,54 +487,7 @@ private extension PushNotificationManager {
399487
_ = registerSalesforceNotifications(completionBlock: nil, failBlock: nil)
400488
}
401489

402-
private func unregisterSalesforceNotifications(for user: UserAccount,
403-
completionBlock: (() -> Void)?) -> Bool {
404-
guard deviceSalesforceId != nil else {
405-
completionBlock?()
406-
return true
407-
}
408-
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-
}
490+
@objc private func onUserLoggedOut(_ notification: Notification) {
491+
restClient = RestClient.shared
451492
}
452493
}

0 commit comments

Comments
 (0)