summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2022-12-13 14:42:12 +0100
committerAndrej Mihajlov <and@mullvad.net>2022-12-13 14:42:12 +0100
commit800c01bf3d521f23b919e7d5bb0c0a2cf386ec01 (patch)
treed7d7d11cac10853d6ba58d7b27f5024350ce89a2
parent7db2d49794a809a14e52c1a72c593bbe6674f26d (diff)
parent39647e3d69e0669fd11e97b33812ad99322b9355 (diff)
downloadmullvadvpn-800c01bf3d521f23b919e7d5bb0c0a2cf386ec01.tar.xz
mullvadvpn-800c01bf3d521f23b919e7d5bb0c0a2cf386ec01.zip
Merge branch 'refresh-account-expiry-notification'
-rw-r--r--ios/CHANGELOG.md1
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj12
-rw-r--r--ios/MullvadVPN/AppDelegate.swift20
-rw-r--r--ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryInAppNotificationProvider.swift140
-rw-r--r--ios/MullvadVPN/Notifications/Notification Providers/AccountExpirySystemNotificationProvider.swift (renamed from ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryNotificationProvider.swift)125
-rw-r--r--ios/MullvadVPN/Notifications/Notification Providers/TunnelStatusNotificationProvider.swift46
-rw-r--r--ios/MullvadVPN/Notifications/NotificationManager.swift2
7 files changed, 209 insertions, 137 deletions
diff --git a/ios/CHANGELOG.md b/ios/CHANGELOG.md
index e8751c1985..6595ac0de3 100644
--- a/ios/CHANGELOG.md
+++ b/ios/CHANGELOG.md
@@ -44,6 +44,7 @@ with the option to buy more time.
- Improve random port distribution. Should be less biased towards port 53.
- Fix invalid map camera position during the app launch and keep it up to date when multitasking.
- Fix animation glitch when expanding partially visible cell in location picker.
+- Periodically refresh account expiry in-app notification.
## Removed
- Remove iOS 12 support.
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 5661dcee7c..a4aba1db17 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -146,6 +146,7 @@
585C6F4C28F80745005196BE /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = 585C6F4B28F80745005196BE /* Logging */; };
585CA70F25F8C44600B47C62 /* UIMetrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585CA70E25F8C44600B47C62 /* UIMetrics.swift */; };
585E820327F3285E00939F0E /* SendStoreReceiptOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585E820227F3285E00939F0E /* SendStoreReceiptOperation.swift */; };
+ 58607A4D2947287800BC467D /* AccountExpiryInAppNotificationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58607A4C2947287800BC467D /* AccountExpiryInAppNotificationProvider.swift */; };
5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */; };
5867770E29096984006F721F /* OutOfTimeInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5867770D29096984006F721F /* OutOfTimeInteractor.swift */; };
58677710290975E9006F721F /* SettingsInteractorFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5867770F290975E8006F721F /* SettingsInteractorFactory.swift */; };
@@ -187,7 +188,7 @@
587B753B2666467500DEF7E9 /* NotificationBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B753A2666467500DEF7E9 /* NotificationBannerView.swift */; };
587B753D2666468F00DEF7E9 /* NotificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B753C2666468F00DEF7E9 /* NotificationController.swift */; };
587B753F2668E5A700DEF7E9 /* NotificationContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B753E2668E5A700DEF7E9 /* NotificationContainerView.swift */; };
- 587B75412668FD7800DEF7E9 /* AccountExpiryNotificationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B75402668FD7700DEF7E9 /* AccountExpiryNotificationProvider.swift */; };
+ 587B75412668FD7800DEF7E9 /* AccountExpirySystemNotificationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B75402668FD7700DEF7E9 /* AccountExpirySystemNotificationProvider.swift */; };
587CBFE322807F530028DED3 /* UIColor+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587CBFE222807F530028DED3 /* UIColor+Helpers.swift */; };
587D96742886D87C00CD8F1C /* DeviceManagementContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587D96732886D87C00CD8F1C /* DeviceManagementContentView.swift */; };
587D9676288989DB00CD8F1C /* NSLayoutConstraint+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587D9675288989DB00CD8F1C /* NSLayoutConstraint+Helpers.swift */; };
@@ -663,6 +664,7 @@
585DA89226B0323E00B8C587 /* TunnelProviderMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelProviderMessage.swift; sourceTree = "<group>"; };
585DA89826B0329200B8C587 /* PacketTunnelStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelStatus.swift; sourceTree = "<group>"; };
585E820227F3285E00939F0E /* SendStoreReceiptOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendStoreReceiptOperation.swift; sourceTree = "<group>"; };
+ 58607A4C2947287800BC467D /* AccountExpiryInAppNotificationProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountExpiryInAppNotificationProvider.swift; sourceTree = "<group>"; };
5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslucentButtonBlurView.swift; sourceTree = "<group>"; };
5866F39B2243B82D00168AE5 /* MullvadVPN.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MullvadVPN.entitlements; sourceTree = "<group>"; };
5867770D29096984006F721F /* OutOfTimeInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutOfTimeInteractor.swift; sourceTree = "<group>"; };
@@ -699,7 +701,7 @@
587B753A2666467500DEF7E9 /* NotificationBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationBannerView.swift; sourceTree = "<group>"; };
587B753C2666468F00DEF7E9 /* NotificationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationController.swift; sourceTree = "<group>"; };
587B753E2668E5A700DEF7E9 /* NotificationContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationContainerView.swift; sourceTree = "<group>"; };
- 587B75402668FD7700DEF7E9 /* AccountExpiryNotificationProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountExpiryNotificationProvider.swift; sourceTree = "<group>"; };
+ 587B75402668FD7700DEF7E9 /* AccountExpirySystemNotificationProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountExpirySystemNotificationProvider.swift; sourceTree = "<group>"; };
587B7544266922BF00DEF7E9 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
587C575226D2615F005EF767 /* PacketTunnelOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelOptions.swift; sourceTree = "<group>"; };
587CBFE222807F530028DED3 /* UIColor+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Helpers.swift"; sourceTree = "<group>"; };
@@ -1179,7 +1181,8 @@
587B75422669034500DEF7E9 /* Notification Providers */ = {
isa = PBXGroup;
children = (
- 587B75402668FD7700DEF7E9 /* AccountExpiryNotificationProvider.swift */,
+ 587B75402668FD7700DEF7E9 /* AccountExpirySystemNotificationProvider.swift */,
+ 58607A4C2947287800BC467D /* AccountExpiryInAppNotificationProvider.swift */,
58A94AE326CFD945001CB97C /* TunnelStatusNotificationProvider.swift */,
);
path = "Notification Providers";
@@ -2193,7 +2196,7 @@
58BFA5CC22A7CE1F00A6173D /* ApplicationConfiguration.swift in Sources */,
5891BF5125E66B1E006D6FB0 /* UIBarButtonItem+KeyboardNavigation.swift in Sources */,
58E511E628DDDEAC00B0BCDE /* CodingErrors+CustomErrorDescription.swift in Sources */,
- 587B75412668FD7800DEF7E9 /* AccountExpiryNotificationProvider.swift in Sources */,
+ 587B75412668FD7800DEF7E9 /* AccountExpirySystemNotificationProvider.swift in Sources */,
587988C728A2A01F00E3DF54 /* AccountDataThrottling.swift in Sources */,
5896CEF226972DEB00B0FAE8 /* AccountContentView.swift in Sources */,
5867771429097BCD006F721F /* PaymentState.swift in Sources */,
@@ -2299,6 +2302,7 @@
5892A45E265FABFF00890742 /* EmptyTableViewHeaderFooterView.swift in Sources */,
580909D32876D09A0078138D /* RevokedDeviceViewController.swift in Sources */,
5835B7CC233B76CB0096D79F /* TunnelManager.swift in Sources */,
+ 58607A4D2947287800BC467D /* AccountExpiryInAppNotificationProvider.swift in Sources */,
06410E07292D108E00AFC18C /* SettingsStore.swift in Sources */,
586A950D290125F0007BAF2B /* PresentAlertOperation.swift in Sources */,
58B93A1326C3F13600A55733 /* TunnelState.swift in Sources */,
diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift
index 7f2cb40392..dfdee88d7e 100644
--- a/ios/MullvadVPN/AppDelegate.swift
+++ b/ios/MullvadVPN/AppDelegate.swift
@@ -389,18 +389,18 @@ 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 = [
- accountExpiryProvider,
TunnelStatusNotificationProvider(tunnelManager: tunnelManager),
+ AccountExpirySystemNotificationProvider(
+ tunnelManager: tunnelManager,
+ defaultActionHandler: {
+ let sceneDelegate = UIApplication.shared.connectedScenes
+ .first?.delegate as? SceneDelegate
+
+ sceneDelegate?.showUserAccount()
+ }
+ ),
+ AccountExpiryInAppNotificationProvider(tunnelManager: tunnelManager),
]
UNUserNotificationCenter.current().delegate = self
}
diff --git a/ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryInAppNotificationProvider.swift b/ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryInAppNotificationProvider.swift
new file mode 100644
index 0000000000..5d9e978e60
--- /dev/null
+++ b/ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryInAppNotificationProvider.swift
@@ -0,0 +1,140 @@
+//
+// AccountExpiryInAppNotificationProvider.swift
+// MullvadVPN
+//
+// Created by pronebird on 12/12/2022.
+// Copyright © 2022 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+
+private let triggerInterval = 3
+private let refreshInterval = 60
+
+final class AccountExpiryInAppNotificationProvider: NotificationProvider, InAppNotificationProvider
+{
+ private var accountExpiry: Date?
+ private var tunnelObserver: TunnelBlockObserver?
+ private var timer: DispatchSourceTimer?
+
+ init(tunnelManager: TunnelManager) {
+ super.init()
+
+ let tunnelObserver = TunnelBlockObserver(
+ didLoadConfiguration: { [weak self] tunnelManager in
+ self?.invalidate(deviceState: tunnelManager.deviceState)
+ },
+ didUpdateDeviceState: { [weak self] tunnelManager, deviceState in
+ self?.invalidate(deviceState: deviceState)
+ }
+ )
+ self.tunnelObserver = tunnelObserver
+
+ tunnelManager.addObserver(tunnelObserver)
+ }
+
+ override var identifier: String {
+ return "net.mullvad.MullvadVPN.AccountExpiryInAppNotification"
+ }
+
+ // MARK: - InAppNotificationProvider
+
+ var notificationDescriptor: InAppNotificationDescriptor? {
+ let now = Date()
+ guard let accountExpiry = accountExpiry, let triggerDate = triggerDate, now >= triggerDate,
+ now < accountExpiry
+ else {
+ return nil
+ }
+
+ let formatter = DateComponentsFormatter()
+ formatter.unitsStyle = .full
+ formatter.allowedUnits = [.minute, .hour, .day]
+ formatter.maximumUnitCount = 1
+
+ let duration: String?
+ if accountExpiry.timeIntervalSince(now) < 60 {
+ duration = NSLocalizedString(
+ "ACCOUNT_EXPIRY_INAPP_NOTIFICATION_LESS_THAN_ONE_MINUTE",
+ value: "Less than a minute",
+ comment: ""
+ )
+ } else {
+ duration = formatter.string(from: now, to: accountExpiry)
+ }
+
+ guard let duration = duration else { return nil }
+
+ return InAppNotificationDescriptor(
+ identifier: identifier,
+ style: .warning,
+ title: NSLocalizedString(
+ "ACCOUNT_EXPIRY_INAPP_NOTIFICATION_TITLE",
+ value: "ACCOUNT CREDIT EXPIRES SOON",
+ comment: "Title for in-app notification, displayed within the last 3 days until account expiry."
+ ),
+ body: String(
+ format: NSLocalizedString(
+ "ACCOUNT_EXPIRY_INAPP_NOTIFICATION_BODY",
+ value: "%@ left. Buy more credit.",
+ comment: "Message for in-app notification, displayed within the last 3 days until account expiry."
+ ), duration
+ )
+ )
+ }
+
+ // MARK: - Private
+
+ private var triggerDate: Date? {
+ guard let accountExpiry = accountExpiry else { return nil }
+
+ return Calendar.current.date(
+ byAdding: .day,
+ value: -triggerInterval,
+ to: accountExpiry
+ )
+ }
+
+ private func invalidate(deviceState: DeviceState) {
+ updateExpiry(deviceState: deviceState)
+ updateTimer()
+ invalidate()
+ }
+
+ private func updateExpiry(deviceState: DeviceState) {
+ accountExpiry = deviceState.accountData?.expiry
+ }
+
+ private func updateTimer() {
+ timer?.cancel()
+
+ guard let triggerDate = triggerDate else {
+ return
+ }
+
+ let now = Date()
+ let fireDate = max(now, triggerDate)
+
+ let timer = DispatchSource.makeTimerSource(queue: .main)
+ timer.setEventHandler { [weak self] in
+ self?.timerDidFire()
+ }
+ timer.schedule(
+ wallDeadline: .now() + fireDate.timeIntervalSince(now),
+ repeating: .seconds(refreshInterval)
+ )
+ timer.activate()
+
+ self.timer = timer
+ }
+
+ private func timerDidFire() {
+ let shouldCancelTimer = accountExpiry.map { $0 <= Date() } ?? true
+
+ if shouldCancelTimer {
+ timer?.cancel()
+ }
+
+ invalidate()
+ }
+}
diff --git a/ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryNotificationProvider.swift b/ios/MullvadVPN/Notifications/Notification Providers/AccountExpirySystemNotificationProvider.swift
index 80b7a06428..c32bd24b28 100644
--- a/ios/MullvadVPN/Notifications/Notification Providers/AccountExpiryNotificationProvider.swift
+++ b/ios/MullvadVPN/Notifications/Notification Providers/AccountExpirySystemNotificationProvider.swift
@@ -1,5 +1,5 @@
//
-// AccountExpiryNotificationProvider.swift
+// AccountExpirySystemNotificationProvider.swift
// MullvadVPN
//
// Created by pronebird on 03/06/2021.
@@ -9,54 +9,35 @@
import Foundation
import UserNotifications
-private let defaultTriggerInterval = 3
+private let triggerInterval = 3
-final class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificationProvider,
- InAppNotificationProvider, TunnelObserver
+final class AccountExpirySystemNotificationProvider: NotificationProvider,
+ SystemNotificationProvider
{
- /// Interval prior to expiry used to calculate when to trigger notifications.
- private let triggerInterval: Int
private var accountExpiry: Date?
+ private var tunnelObserver: TunnelBlockObserver?
+ private var defaultActionHandler: (() -> Void)?
- var defaultActionHandler: (() -> Void)?
-
- override var identifier: String {
- return "net.mullvad.MullvadVPN.AccountExpiryNotification"
- }
-
- init(tunnelManager: TunnelManager, triggerInterval: Int = defaultTriggerInterval) {
- self.triggerInterval = triggerInterval
-
+ init(tunnelManager: TunnelManager, defaultActionHandler: (() -> Void)? = nil) {
super.init()
- tunnelManager.addObserver(self)
- accountExpiry = tunnelManager.deviceState.accountData?.expiry
- }
-
- private var trigger: UNNotificationTrigger? {
- guard let accountExpiry = accountExpiry else { return nil }
-
- // Subtract 3 days from expiry date
- guard let triggerDate = Calendar.current.date(
- byAdding: .day,
- value: -triggerInterval,
- to: accountExpiry
- ) else { return nil }
-
- // Do not produce notification if less than 3 days left till expiry
- guard triggerDate > Date() else { return nil }
-
- // Create date components for calendar trigger
- let dateComponents = Calendar.current.dateComponents(
- [.second, .minute, .hour, .day, .month, .year],
- from: triggerDate
+ let tunnelObserver = TunnelBlockObserver(
+ didLoadConfiguration: { [weak self] tunnelManager in
+ self?.invalidate(deviceState: tunnelManager.deviceState)
+ },
+ didUpdateDeviceState: { [weak self] tunnelManager, deviceState in
+ self?.invalidate(deviceState: deviceState)
+ }
)
- return UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
+ tunnelManager.addObserver(tunnelObserver)
+
+ self.tunnelObserver = tunnelObserver
+ self.defaultActionHandler = defaultActionHandler
}
- private var shouldRemovePendingOrDeliveredRequests: Bool {
- return accountExpiry == nil
+ override var identifier: String {
+ return "net.mullvad.MullvadVPN.AccountExpiryNotification"
}
// MARK: - SystemNotificationProvider
@@ -113,75 +94,35 @@ final class AccountExpiryNotificationProvider: NotificationProvider, SystemNotif
return true
}
- // MARK: - InAppNotificationProvider
+ // MARK: - Private
- var notificationDescriptor: InAppNotificationDescriptor? {
+ private var trigger: UNNotificationTrigger? {
guard let accountExpiry = accountExpiry else { return nil }
- // Subtract 3 days from expiry date
guard let triggerDate = Calendar.current.date(
byAdding: .day,
value: -triggerInterval,
to: accountExpiry
) else { return nil }
- // Only produce in-app notification within the last 3 days till expiry
- let now = Date()
- guard triggerDate < now, now < accountExpiry else { return nil }
+ // Do not produce notification if less than 3 days left till expiry
+ guard triggerDate > Date() else { return nil }
- // Format the remaining duration
- let formatter = DateComponentsFormatter()
- formatter.unitsStyle = .full
- formatter.allowedUnits = [.minute, .hour, .day]
- formatter.maximumUnitCount = 1
+ // Create date components for calendar trigger
+ let dateComponents = Calendar.current.dateComponents(
+ [.second, .minute, .hour, .day, .month, .year],
+ from: triggerDate
+ )
- guard let duration = formatter.string(from: now, to: accountExpiry) else { return nil }
+ return UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
+ }
- return InAppNotificationDescriptor(
- identifier: identifier,
- style: .warning,
- title: NSLocalizedString(
- "ACCOUNT_EXPIRY_INAPP_NOTIFICATION_TITLE",
- value: "ACCOUNT CREDIT EXPIRES SOON",
- comment: "Title for in-app notification, displayed within the last 3 days until account expiry."
- ),
- body: String(
- format: NSLocalizedString(
- "ACCOUNT_EXPIRY_INAPP_NOTIFICATION_BODY",
- value: "%@ left. Buy more credit.",
- comment: "Message for in-app notification, displayed within the last 3 days until account expiry."
- ), duration
- )
- )
+ private var shouldRemovePendingOrDeliveredRequests: Bool {
+ return accountExpiry == nil
}
private func invalidate(deviceState: DeviceState) {
accountExpiry = deviceState.accountData?.expiry
invalidate()
}
-
- // MARK: - TunnelObserver
-
- func tunnelManagerDidLoadConfiguration(_ manager: TunnelManager) {
- invalidate(deviceState: manager.deviceState)
- }
-
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelStatus tunnelStatus: TunnelStatus) {
- // no-op
- }
-
- func tunnelManager(_ manager: TunnelManager, didFailWithError error: Error) {
- // no-op
- }
-
- func tunnelManager(
- _ manager: TunnelManager,
- didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
- ) {
- // no-op
- }
-
- func tunnelManager(_ manager: TunnelManager, didUpdateDeviceState deviceState: DeviceState) {
- invalidate(deviceState: deviceState)
- }
}
diff --git a/ios/MullvadVPN/Notifications/Notification Providers/TunnelStatusNotificationProvider.swift b/ios/MullvadVPN/Notifications/Notification Providers/TunnelStatusNotificationProvider.swift
index df59cc1433..33642621d3 100644
--- a/ios/MullvadVPN/Notifications/Notification Providers/TunnelStatusNotificationProvider.swift
+++ b/ios/MullvadVPN/Notifications/Notification Providers/TunnelStatusNotificationProvider.swift
@@ -8,12 +8,11 @@
import Foundation
-final class TunnelStatusNotificationProvider: NotificationProvider, InAppNotificationProvider,
- TunnelObserver
-{
+final class TunnelStatusNotificationProvider: NotificationProvider, InAppNotificationProvider {
private var isWaitingForConnectivity = false
private var packetTunnelError: String?
private var tunnelManagerError: Error?
+ private var tunnelObserver: TunnelBlockObserver?
override var identifier: String {
return "net.mullvad.MullvadVPN.TunnelStatusNotificationProvider"
@@ -34,8 +33,20 @@ final class TunnelStatusNotificationProvider: NotificationProvider, InAppNotific
init(tunnelManager: TunnelManager) {
super.init()
- tunnelManager.addObserver(self)
- handleTunnelStatus(tunnelManager.tunnelStatus)
+ let tunnelObserver = TunnelBlockObserver(
+ didLoadConfiguration: { [weak self] tunnelManager in
+ self?.handleTunnelStatus(tunnelManager.tunnelStatus)
+ },
+ didUpdateTunnelStatus: { [weak self] tunnelManager, tunnelStatus in
+ self?.handleTunnelStatus(tunnelStatus)
+ },
+ didFailWithError: { [weak self] tunnelManager, error in
+ self?.tunnelManagerError = error
+ }
+ )
+ self.tunnelObserver = tunnelObserver
+
+ tunnelManager.addObserver(tunnelObserver)
}
// MARK: - Private
@@ -174,29 +185,4 @@ final class TunnelStatusNotificationProvider: NotificationProvider, InAppNotific
)
)
}
-
- // MARK: - TunnelObserver
-
- func tunnelManagerDidLoadConfiguration(_ manager: TunnelManager) {
- // no-op
- }
-
- func tunnelManager(_ manager: TunnelManager, didUpdateTunnelStatus tunnelStatus: TunnelStatus) {
- handleTunnelStatus(tunnelStatus)
- }
-
- func tunnelManager(
- _ manager: TunnelManager,
- didUpdateTunnelSettings tunnelSettings: TunnelSettingsV2
- ) {
- // no-op
- }
-
- func tunnelManager(_ manager: TunnelManager, didUpdateDeviceState deviceState: DeviceState) {
- // no-op
- }
-
- func tunnelManager(_ manager: TunnelManager, didFailWithError error: Error) {
- tunnelManagerError = error
- }
}
diff --git a/ios/MullvadVPN/Notifications/NotificationManager.swift b/ios/MullvadVPN/Notifications/NotificationManager.swift
index 7cf48066cb..f129fc56ce 100644
--- a/ios/MullvadVPN/Notifications/NotificationManager.swift
+++ b/ios/MullvadVPN/Notifications/NotificationManager.swift
@@ -161,7 +161,7 @@ final class NotificationManager: NotificationProviderDelegate {
// MARK: - NotificationProviderDelegate
func notificationProviderDidInvalidate(_ notificationProvider: NotificationProvider) {
- assert(Thread.isMainThread)
+ dispatchPrecondition(condition: .onQueue(.main))
// Invalidate system notification
if let notificationProvider = notificationProvider as? SystemNotificationProvider {