diff options
4 files changed, 54 insertions, 19 deletions
diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift index eec04a0851..7f2cb40392 100644 --- a/ios/MullvadVPN/AppDelegate.swift +++ b/ios/MullvadVPN/AppDelegate.swift @@ -389,8 +389,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD } private func setupNotificationHandler() { + let accountExpiryProvider = AccountExpiryNotificationProvider(tunnelManager: tunnelManager) + + accountExpiryProvider.defaultActionHandler = { + let sceneDelegate = UIApplication.shared.connectedScenes + .first?.delegate as? SceneDelegate + + sceneDelegate?.showUserAccount() + } + NotificationManager.shared.notificationProviders = [ - AccountExpiryNotificationProvider(tunnelManager: tunnelManager), + accountExpiryProvider, TunnelStatusNotificationProvider(tunnelManager: tunnelManager), ] UNUserNotificationCenter.current().delegate = self @@ -416,14 +425,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD withCompletionHandler completionHandler: @escaping () -> Void ) { let blockOperation = AsyncBlockOperation(dispatchQueue: .main) { - if response.notification.request.identifier == accountExpiryNotificationIdentifier, - response.actionIdentifier == UNNotificationDefaultActionIdentifier - { - let sceneDelegate = UIApplication.shared.connectedScenes - .first?.delegate as? SceneDelegate - - sceneDelegate?.showUserAccount() - } + NotificationManager.shared.handleSystemNotificationResponse(response) completionHandler() } diff --git a/ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryNotificationProvider.swift b/ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryNotificationProvider.swift index 2562b77eaa..e2514d7398 100644 --- a/ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryNotificationProvider.swift +++ b/ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryNotificationProvider.swift @@ -9,19 +9,19 @@ import Foundation import UserNotifications -let accountExpiryNotificationIdentifier = "net.mullvad.MullvadVPN.AccountExpiryNotification" private let defaultTriggerInterval = 3 final class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificationProvider, InAppNotificationProvider, TunnelObserver { - private var accountExpiry: Date? - /// Interval prior to expiry used to calculate when to trigger notifications. private let triggerInterval: Int + private var accountExpiry: Date? + + var defaultActionHandler: (() -> Void)? override var identifier: String { - return accountExpiryNotificationIdentifier + return "net.mullvad.MullvadVPN.AccountExpiryNotification" } init(tunnelManager: TunnelManager, triggerInterval: Int = defaultTriggerInterval) { @@ -101,6 +101,18 @@ final class AccountExpiryNotificationProvider: NotificationProvider, SystemNotif return shouldRemovePendingOrDeliveredRequests } + func handleResponse(_ response: UNNotificationResponse) -> Bool { + guard response.notification.request.identifier == identifier else { + return false + } + + if response.actionIdentifier == UNNotificationDefaultActionIdentifier { + defaultActionHandler?() + } + + return true + } + // MARK: - InAppNotificationProvider var notificationDescriptor: InAppNotificationDescriptor? { diff --git a/ios/MullvadVPN/Notifications/NotificationManager.swift b/ios/MullvadVPN/Notifications/NotificationManager.swift index 4fefe3daa4..7cf48066cb 100644 --- a/ios/MullvadVPN/Notifications/NotificationManager.swift +++ b/ios/MullvadVPN/Notifications/NotificationManager.swift @@ -12,19 +12,28 @@ import UserNotifications final class NotificationManager: NotificationProviderDelegate { private lazy var logger = Logger(label: "NotificationManager") + private var _notificationProviders: [NotificationProvider] = [] + private var inAppNotificationDescriptors: [InAppNotificationDescriptor] = [] - var notificationProviders: [NotificationProvider] = [] { - didSet { + var notificationProviders: [NotificationProvider] { + set(newNotificationProviders) { dispatchPrecondition(condition: .onQueue(.main)) - for notificationProvider in notificationProviders { - notificationProvider.delegate = self + for oldNotificationProvider in _notificationProviders { + oldNotificationProvider.delegate = nil + } + + for newNotificationProvider in newNotificationProviders { + newNotificationProvider.delegate = self } + + _notificationProviders = newNotificationProviders + } + get { + return _notificationProviders } } - private var inAppNotificationDescriptors: [InAppNotificationDescriptor] = [] - weak var delegate: NotificationManagerDelegate? { didSet { dispatchPrecondition(condition: .onQueue(.main)) @@ -108,6 +117,14 @@ final class NotificationManager: NotificationProviderDelegate { ) } + func handleSystemNotificationResponse(_ response: UNNotificationResponse) { + for case let notificationProvider as SystemNotificationProvider in notificationProviders { + if notificationProvider.handleResponse(response) { + return + } + } + } + // MARK: - Private private func requestNotificationPermissions(completion: @escaping (Bool) -> Void) { diff --git a/ios/MullvadVPN/Notifications/SystemNotificationProvider.swift b/ios/MullvadVPN/Notifications/SystemNotificationProvider.swift index 110e078aba..f346e3e230 100644 --- a/ios/MullvadVPN/Notifications/SystemNotificationProvider.swift +++ b/ios/MullvadVPN/Notifications/SystemNotificationProvider.swift @@ -19,4 +19,8 @@ protocol SystemNotificationProvider: NotificationProviderProtocol { /// Whether any delivered requests should be removed. var shouldRemoveDeliveredRequests: Bool { get } + + /// Handle system notification response. + /// Return `true` if response was handled by this provider, otherwise `false`. + func handleResponse(_ response: UNNotificationResponse) -> Bool } |
