diff --git a/app-ios/TutanotaNotificationExtension/NotificationService.swift b/app-ios/TutanotaNotificationExtension/NotificationService.swift index d0ec27a2f5..091b6a845c 100644 --- a/app-ios/TutanotaNotificationExtension/NotificationService.swift +++ b/app-ios/TutanotaNotificationExtension/NotificationService.swift @@ -6,6 +6,8 @@ import tutasdk var suspensionEndTime: Date? class NotificationService: UNNotificationServiceExtension { + private let notificationStorage = NotificationStorage(userPreferencesProvider: UserPreferencesProviderImpl()) + private var contentHandler: ((UNNotificationContent) -> Void)? private var bestAttemptContent: UNMutableNotificationContent? private let urlSession: URLSession = makeUrlSession() @@ -13,8 +15,13 @@ class NotificationService: UNNotificationServiceExtension { override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler + + notificationStorage.incrementNotificationCount() + bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent { + bestAttemptContent.badge = notificationStorage.notificationCount as NSNumber + Task { await notificationHandleTask(bestAttemptContent) contentHandler(bestAttemptContent) @@ -47,7 +54,6 @@ class NotificationService: UNNotificationServiceExtension { let keychainManager = KeychainManager(keyGenerator: KeyGenerator()) let keychainEncryption = KeychainEncryption(keychainManager: keychainManager) let credentialsFacade = IosNativeCredentialsFacade(keychainEncryption: keychainEncryption, credentialsDb: credentialsDb, cryptoFns: CryptoFunctions()) - let notificationStorage = NotificationStorage(userPreferencesProvider: UserPreferencesProviderImpl()) let mailId = content.userInfo["mailId"] as? [String] let userId = content.userInfo["userId"] as? String diff --git a/app-ios/TutanotaSharedFramework/Notifications/NotificationStorage.swift b/app-ios/TutanotaSharedFramework/Notifications/NotificationStorage.swift index 385e6ff819..08c500009f 100644 --- a/app-ios/TutanotaSharedFramework/Notifications/NotificationStorage.swift +++ b/app-ios/TutanotaSharedFramework/Notifications/NotificationStorage.swift @@ -7,6 +7,7 @@ private let LAST_PROCESSED_NOTIFICAION_ID_KEY = "lastProcessedNotificationId" private let LAST_MISSED_NOTIFICATION_CHECK_TIME = "lastMissedNotificationCheckTime" private let EXTENDED_NOTIFICATION_MODE = "extendedNotificationMode" private let RECEIVE_CALENDAR_NOTIFICATION_CONFIG = "receiveCalendarNotificationConfig" +private let NOTIFICAITON_COUNT_KEY = "notificationCount" public class NotificationStorage { private let userPreferencesProvider: UserPreferencesProvider @@ -79,6 +80,13 @@ public class NotificationStorage { set { return self.userPreferencesProvider.setValue(newValue, forKey: LAST_MISSED_NOTIFICATION_CHECK_TIME) } } + /// Count of email notifications received but not viewed + public var notificationCount: Int { get { self.userPreferencesProvider.getObject(forKey: NOTIFICAITON_COUNT_KEY) as! Int? ?? 0 } } + + public func incrementNotificationCount() { self.userPreferencesProvider.setValue(self.notificationCount + 1, forKey: NOTIFICAITON_COUNT_KEY) } + + public func resetNotificaitonCount() { self.userPreferencesProvider.setValue(0, forKey: NOTIFICAITON_COUNT_KEY) } + public func clear() { TUTSLog("UserPreference clear") let sseInfo = self.sseInfo diff --git a/app-ios/TutanotaSharedFramework/Notifications/SdkRestClient.swift b/app-ios/TutanotaSharedFramework/Notifications/SdkRestClient.swift index 5d1e198156..93b4480102 100644 --- a/app-ios/TutanotaSharedFramework/Notifications/SdkRestClient.swift +++ b/app-ios/TutanotaSharedFramework/Notifications/SdkRestClient.swift @@ -28,6 +28,14 @@ public class SdkRestClient: RestClient { private func mapExceptionToError(e: Error) -> RestClientError { // why we don't match on e? see: sdkFileClient::mapExceptionToError TUTSLog("Exception in SdkRestClient: \(e). Assuming .Unknown") + if let e = e as? URLError { + switch e.code { + case .notConnectedToInternet, .timedOut, .cannotFindHost, .networkConnectionLost, URLError.Code.notConnectedToInternet, + URLError.Code.dnsLookupFailed: + return .NetworkError + default: break + } + } return RestClientError.Unknown } } diff --git a/app-ios/calendar/Sources/AppDelegate.swift b/app-ios/calendar/Sources/AppDelegate.swift index d097967241..77519295e6 100644 --- a/app-ios/calendar/Sources/AppDelegate.swift +++ b/app-ios/calendar/Sources/AppDelegate.swift @@ -13,6 +13,8 @@ public let TUTA_CALENDAR_INTEROP_SCHEME = "tutacalendar" private var viewController: ViewController! private let urlSession: URLSession = makeUrlSession() + private var notificationStorage: NotificationStorage! + func registerForPushNotifications() async throws -> String { #if targetEnvironment(simulator) return "" @@ -37,7 +39,7 @@ public let TUTA_CALENDAR_INTEROP_SCHEME = "tutacalendar" spawnTransactionFinisher() let userPreferencesProvider = UserPreferencesProviderImpl() - let notificationStorage = NotificationStorage(userPreferencesProvider: userPreferencesProvider) + self.notificationStorage = NotificationStorage(userPreferencesProvider: userPreferencesProvider) let keychainManager = KeychainManager(keyGenerator: KeyGenerator()) let keychainEncryption = KeychainEncryption(keychainManager: keychainManager) let dateProvider = SystemDateProvider() diff --git a/app-ios/tutanota/Sources/AppDelegate.swift b/app-ios/tutanota/Sources/AppDelegate.swift index 2afb034d56..64881ea8e4 100644 --- a/app-ios/tutanota/Sources/AppDelegate.swift +++ b/app-ios/tutanota/Sources/AppDelegate.swift @@ -16,6 +16,8 @@ public let MAILTO_SCHEME = "mailto" private var viewController: ViewController! private let urlSession: URLSession = makeUrlSession() + private var notificationStorage: NotificationStorage! + @MainActor func registerForPushNotifications() async throws -> String { #if targetEnvironment(simulator) return "" @@ -32,7 +34,7 @@ public let MAILTO_SCHEME = "mailto" spawnTransactionFinisher() let userPreferencesProvider = UserPreferencesProviderImpl() - let notificationStorage = NotificationStorage(userPreferencesProvider: userPreferencesProvider) + self.notificationStorage = NotificationStorage(userPreferencesProvider: userPreferencesProvider) let keychainManager = KeychainManager(keyGenerator: KeyGenerator()) let keychainEncryption = KeychainEncryption(keychainManager: keychainManager) let dateProvider: SystemDateProvider = SystemDateProvider() @@ -92,7 +94,10 @@ public let MAILTO_SCHEME = "mailto" return true } - func applicationWillEnterForeground(_ application: UIApplication) { UIApplication.shared.applicationIconBadgeNumber = 0 } + func applicationWillEnterForeground(_ application: UIApplication) { + UIApplication.shared.applicationIconBadgeNumber = 0 + self.notificationStorage.resetNotificaitonCount() + } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let stringToken = deviceTokenAsString(deviceToken: deviceToken)