mirror of
https://github.com/tutao/tutanota.git
synced 2025-10-19 07:53:47 +00:00
[ios] Add notification counter badge to app icon
Add a persistent counter that is incremented from notification extension. The counter is reset on app being put into foreground. Close #1757
This commit is contained in:
parent
b1300345d4
commit
9100edc7b8
5 changed files with 33 additions and 4 deletions
|
@ -6,6 +6,8 @@ import tutasdk
|
||||||
var suspensionEndTime: Date?
|
var suspensionEndTime: Date?
|
||||||
|
|
||||||
class NotificationService: UNNotificationServiceExtension {
|
class NotificationService: UNNotificationServiceExtension {
|
||||||
|
private let notificationStorage = NotificationStorage(userPreferencesProvider: UserPreferencesProviderImpl())
|
||||||
|
|
||||||
private var contentHandler: ((UNNotificationContent) -> Void)?
|
private var contentHandler: ((UNNotificationContent) -> Void)?
|
||||||
private var bestAttemptContent: UNMutableNotificationContent?
|
private var bestAttemptContent: UNMutableNotificationContent?
|
||||||
private let urlSession: URLSession = makeUrlSession()
|
private let urlSession: URLSession = makeUrlSession()
|
||||||
|
@ -13,8 +15,13 @@ class NotificationService: UNNotificationServiceExtension {
|
||||||
|
|
||||||
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||||
self.contentHandler = contentHandler
|
self.contentHandler = contentHandler
|
||||||
|
|
||||||
|
notificationStorage.incrementNotificationCount()
|
||||||
|
|
||||||
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
||||||
if let bestAttemptContent {
|
if let bestAttemptContent {
|
||||||
|
bestAttemptContent.badge = notificationStorage.notificationCount as NSNumber
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
await notificationHandleTask(bestAttemptContent)
|
await notificationHandleTask(bestAttemptContent)
|
||||||
contentHandler(bestAttemptContent)
|
contentHandler(bestAttemptContent)
|
||||||
|
@ -47,7 +54,6 @@ class NotificationService: UNNotificationServiceExtension {
|
||||||
let keychainManager = KeychainManager(keyGenerator: KeyGenerator())
|
let keychainManager = KeychainManager(keyGenerator: KeyGenerator())
|
||||||
let keychainEncryption = KeychainEncryption(keychainManager: keychainManager)
|
let keychainEncryption = KeychainEncryption(keychainManager: keychainManager)
|
||||||
let credentialsFacade = IosNativeCredentialsFacade(keychainEncryption: keychainEncryption, credentialsDb: credentialsDb, cryptoFns: CryptoFunctions())
|
let credentialsFacade = IosNativeCredentialsFacade(keychainEncryption: keychainEncryption, credentialsDb: credentialsDb, cryptoFns: CryptoFunctions())
|
||||||
let notificationStorage = NotificationStorage(userPreferencesProvider: UserPreferencesProviderImpl())
|
|
||||||
|
|
||||||
let mailId = content.userInfo["mailId"] as? [String]
|
let mailId = content.userInfo["mailId"] as? [String]
|
||||||
let userId = content.userInfo["userId"] as? String
|
let userId = content.userInfo["userId"] as? String
|
||||||
|
|
|
@ -7,6 +7,7 @@ private let LAST_PROCESSED_NOTIFICAION_ID_KEY = "lastProcessedNotificationId"
|
||||||
private let LAST_MISSED_NOTIFICATION_CHECK_TIME = "lastMissedNotificationCheckTime"
|
private let LAST_MISSED_NOTIFICATION_CHECK_TIME = "lastMissedNotificationCheckTime"
|
||||||
private let EXTENDED_NOTIFICATION_MODE = "extendedNotificationMode"
|
private let EXTENDED_NOTIFICATION_MODE = "extendedNotificationMode"
|
||||||
private let RECEIVE_CALENDAR_NOTIFICATION_CONFIG = "receiveCalendarNotificationConfig"
|
private let RECEIVE_CALENDAR_NOTIFICATION_CONFIG = "receiveCalendarNotificationConfig"
|
||||||
|
private let NOTIFICAITON_COUNT_KEY = "notificationCount"
|
||||||
|
|
||||||
public class NotificationStorage {
|
public class NotificationStorage {
|
||||||
private let userPreferencesProvider: UserPreferencesProvider
|
private let userPreferencesProvider: UserPreferencesProvider
|
||||||
|
@ -79,6 +80,13 @@ public class NotificationStorage {
|
||||||
set { return self.userPreferencesProvider.setValue(newValue, forKey: LAST_MISSED_NOTIFICATION_CHECK_TIME) }
|
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() {
|
public func clear() {
|
||||||
TUTSLog("UserPreference clear")
|
TUTSLog("UserPreference clear")
|
||||||
let sseInfo = self.sseInfo
|
let sseInfo = self.sseInfo
|
||||||
|
|
|
@ -28,6 +28,14 @@ public class SdkRestClient: RestClient {
|
||||||
private func mapExceptionToError(e: Error) -> RestClientError {
|
private func mapExceptionToError(e: Error) -> RestClientError {
|
||||||
// why we don't match on e? see: sdkFileClient::mapExceptionToError
|
// why we don't match on e? see: sdkFileClient::mapExceptionToError
|
||||||
TUTSLog("Exception in SdkRestClient: \(e). Assuming .Unknown")
|
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
|
return RestClientError.Unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ public let TUTA_CALENDAR_INTEROP_SCHEME = "tutacalendar"
|
||||||
private var viewController: ViewController!
|
private var viewController: ViewController!
|
||||||
private let urlSession: URLSession = makeUrlSession()
|
private let urlSession: URLSession = makeUrlSession()
|
||||||
|
|
||||||
|
private var notificationStorage: NotificationStorage!
|
||||||
|
|
||||||
func registerForPushNotifications() async throws -> String {
|
func registerForPushNotifications() async throws -> String {
|
||||||
#if targetEnvironment(simulator)
|
#if targetEnvironment(simulator)
|
||||||
return ""
|
return ""
|
||||||
|
@ -37,7 +39,7 @@ public let TUTA_CALENDAR_INTEROP_SCHEME = "tutacalendar"
|
||||||
spawnTransactionFinisher()
|
spawnTransactionFinisher()
|
||||||
|
|
||||||
let userPreferencesProvider = UserPreferencesProviderImpl()
|
let userPreferencesProvider = UserPreferencesProviderImpl()
|
||||||
let notificationStorage = NotificationStorage(userPreferencesProvider: userPreferencesProvider)
|
self.notificationStorage = NotificationStorage(userPreferencesProvider: userPreferencesProvider)
|
||||||
let keychainManager = KeychainManager(keyGenerator: KeyGenerator())
|
let keychainManager = KeychainManager(keyGenerator: KeyGenerator())
|
||||||
let keychainEncryption = KeychainEncryption(keychainManager: keychainManager)
|
let keychainEncryption = KeychainEncryption(keychainManager: keychainManager)
|
||||||
let dateProvider = SystemDateProvider()
|
let dateProvider = SystemDateProvider()
|
||||||
|
|
|
@ -16,6 +16,8 @@ public let MAILTO_SCHEME = "mailto"
|
||||||
private var viewController: ViewController!
|
private var viewController: ViewController!
|
||||||
private let urlSession: URLSession = makeUrlSession()
|
private let urlSession: URLSession = makeUrlSession()
|
||||||
|
|
||||||
|
private var notificationStorage: NotificationStorage!
|
||||||
|
|
||||||
@MainActor func registerForPushNotifications() async throws -> String {
|
@MainActor func registerForPushNotifications() async throws -> String {
|
||||||
#if targetEnvironment(simulator)
|
#if targetEnvironment(simulator)
|
||||||
return ""
|
return ""
|
||||||
|
@ -32,7 +34,7 @@ public let MAILTO_SCHEME = "mailto"
|
||||||
spawnTransactionFinisher()
|
spawnTransactionFinisher()
|
||||||
|
|
||||||
let userPreferencesProvider = UserPreferencesProviderImpl()
|
let userPreferencesProvider = UserPreferencesProviderImpl()
|
||||||
let notificationStorage = NotificationStorage(userPreferencesProvider: userPreferencesProvider)
|
self.notificationStorage = NotificationStorage(userPreferencesProvider: userPreferencesProvider)
|
||||||
let keychainManager = KeychainManager(keyGenerator: KeyGenerator())
|
let keychainManager = KeychainManager(keyGenerator: KeyGenerator())
|
||||||
let keychainEncryption = KeychainEncryption(keychainManager: keychainManager)
|
let keychainEncryption = KeychainEncryption(keychainManager: keychainManager)
|
||||||
let dateProvider: SystemDateProvider = SystemDateProvider()
|
let dateProvider: SystemDateProvider = SystemDateProvider()
|
||||||
|
@ -92,7 +94,10 @@ public let MAILTO_SCHEME = "mailto"
|
||||||
return true
|
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) {
|
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
||||||
let stringToken = deviceTokenAsString(deviceToken: deviceToken)
|
let stringToken = deviceTokenAsString(deviceToken: deviceToken)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue