зеркало из https://github.com/nextcloud/talk-ios.git
Query notifications in background fetch
This will show a local notification in case we missed a push notification Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
This commit is contained in:
Родитель
0ce79b16b9
Коммит
ddaf76f385
|
@ -400,6 +400,17 @@
|
|||
|
||||
[NCUtils log:@"Start performBackgroundFetchWithCompletionHandler"];
|
||||
|
||||
dispatch_group_enter(backgroundRefreshGroup);
|
||||
[[NCNotificationController sharedInstance] checkForNewNotificationsWithCompletionBlock:^(NSError *error) {
|
||||
[NCUtils log:@"CompletionHandler checkForNewNotificationsWithCompletionBlock"];
|
||||
|
||||
if (error) {
|
||||
errorOccurred = YES;
|
||||
}
|
||||
|
||||
dispatch_group_leave(backgroundRefreshGroup);
|
||||
}];
|
||||
|
||||
dispatch_group_enter(backgroundRefreshGroup);
|
||||
[[NCRoomsManager sharedInstance] updateRoomsAndChatsUpdatingUserStatus:NO withCompletionBlock:^(NSError *error) {
|
||||
[NCUtils log:@"CompletionHandler updateRoomsAndChatsUpdatingUserStatus"];
|
||||
|
|
|
@ -27,11 +27,14 @@
|
|||
extern NSString * const NCNotificationControllerWillPresentNotification;
|
||||
extern NSString * const NCLocalNotificationJoinChatNotification;
|
||||
|
||||
typedef void (^CheckForNewNotificationsWithCompletionBlock)(NSError *error);
|
||||
|
||||
typedef enum {
|
||||
kNCLocalNotificationTypeMissedCall = 1,
|
||||
kNCLocalNotificationTypeCancelledCall,
|
||||
kNCLocalNotificationTypeFailedSendChat,
|
||||
kNCLocalNotificationTypeCallFromOldAccount
|
||||
kNCLocalNotificationTypeCallFromOldAccount,
|
||||
kNCLocalNotificationTypeChatNotification
|
||||
} NCLocalNotificationType;
|
||||
|
||||
@interface NCNotificationController : NSObject
|
||||
|
@ -44,5 +47,6 @@ typedef enum {
|
|||
- (void)showIncomingCallForPushNotification:(NCPushNotification *)pushNotification;
|
||||
- (void)showIncomingCallForOldAccount;
|
||||
- (void)removeAllNotificationsForAccountId:(NSString *)accountId;
|
||||
- (void)checkForNewNotificationsWithCompletionBlock:(CheckForNewNotificationsWithCompletionBlock)block;
|
||||
|
||||
@end
|
||||
|
|
|
@ -180,6 +180,32 @@ NSString * const NCLocalNotificationJoinChatNotification = @"NCLocalN
|
|||
[[CallKitManager sharedInstance] reportIncomingCallForOldAccount];
|
||||
}
|
||||
|
||||
- (void)showLocalNotificationForChatNotification:(NCNotification *)notification forAccountId:(NSString *)accountId
|
||||
{
|
||||
UNMutableNotificationContent *content = [UNMutableNotificationContent new];
|
||||
content.title = notification.chatMessageTitle;
|
||||
content.body = notification.message;
|
||||
content.summaryArgument = notification.chatMessageAuthor;
|
||||
content.threadIdentifier = notification.roomToken;
|
||||
content.sound = [UNNotificationSound defaultSound];
|
||||
|
||||
// Currently not supported for local notifications
|
||||
//content.categoryIdentifier = @"CATEGORY_CHAT";
|
||||
|
||||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:notification.roomToken forKey:@"roomToken"];
|
||||
[userInfo setObject:accountId forKey:@"accountId"];
|
||||
[userInfo setValue:@(kNCLocalNotificationTypeChatNotification) forKey:@"localNotificationType"];
|
||||
content.userInfo = userInfo;
|
||||
|
||||
NSString *identifier = [NSString stringWithFormat:@"ChatNotification-%ld", notification.notificationId];
|
||||
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.1 repeats:NO];
|
||||
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
|
||||
[_notificationCenter addNotificationRequest:request withCompletionHandler:nil];
|
||||
|
||||
[[NCDatabaseManager sharedInstance] increaseUnreadBadgeNumberForAccountId:accountId];
|
||||
[self updateAppIconBadgeNumber];
|
||||
}
|
||||
|
||||
- (void)updateAppIconBadgeNumber
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
@ -255,6 +281,70 @@ NSString * const NCLocalNotificationJoinChatNotification = @"NCLocalN
|
|||
[self updateAppIconBadgeNumber];
|
||||
}
|
||||
|
||||
- (void)checkForNewNotificationsWithCompletionBlock:(CheckForNewNotificationsWithCompletionBlock)block
|
||||
{
|
||||
dispatch_group_t notificationsGroup = dispatch_group_create();
|
||||
|
||||
for (TalkAccount *account in [TalkAccount allObjects]) {
|
||||
ServerCapabilities *serverCapabilities = [[NCDatabaseManager sharedInstance] serverCapabilitiesForAccountId:account.accountId];
|
||||
|
||||
if (!serverCapabilities || !serverCapabilities.notificationsAppEnabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dispatch_group_enter(notificationsGroup);
|
||||
|
||||
[[NCAPIController sharedInstance] getServerNotificationsForAccount:account withLastETag:account.lastNotificationETag withCompletionBlock:^(NSArray *notifications, NSString* ETag, NSError *error) {
|
||||
if (error) {
|
||||
dispatch_group_leave(notificationsGroup);
|
||||
return;
|
||||
}
|
||||
|
||||
NSInteger lastNotificationId = 0;
|
||||
|
||||
for (NSDictionary *notification in notifications) {
|
||||
NCNotification *serverNotification = [NCNotification notificationWithDictionary:notification];
|
||||
|
||||
// Only process chat notifications from Talk
|
||||
if (!serverNotification || ![serverNotification.app isEqualToString:kNCPNAppIdKey] || serverNotification.notificationType != kNCNotificationTypeChat) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lastNotificationId < serverNotification.notificationId) {
|
||||
lastNotificationId = serverNotification.notificationId;
|
||||
}
|
||||
|
||||
if (account.lastNotificationId != 0 && serverNotification.notificationId > account.lastNotificationId) {
|
||||
// Don't show notifications if this is the first time we retrieve notifications for this account
|
||||
// Otherwise after adding a new account all unread notifications from the server would be shown
|
||||
|
||||
[self showLocalNotificationForChatNotification:serverNotification forAccountId:account.accountId];
|
||||
}
|
||||
}
|
||||
|
||||
RLMRealm *realm = [RLMRealm defaultRealm];
|
||||
[realm transactionWithBlock:^{
|
||||
NSPredicate *query = [NSPredicate predicateWithFormat:@"accountId = %@", account.accountId];
|
||||
TalkAccount *managedAccount = [TalkAccount objectsWithPredicate:query].firstObject;
|
||||
managedAccount.lastNotificationETag = ETag;
|
||||
|
||||
if (managedAccount.lastNotificationId < lastNotificationId) {
|
||||
managedAccount.lastNotificationId = lastNotificationId;
|
||||
}
|
||||
}];
|
||||
|
||||
dispatch_group_leave(notificationsGroup);
|
||||
}];
|
||||
}
|
||||
|
||||
dispatch_group_notify(notificationsGroup, dispatch_get_main_queue(), ^{
|
||||
// Notify backgroundFetch that we're finished
|
||||
if (block) {
|
||||
block(nil);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - UNUserNotificationCenter delegate
|
||||
|
||||
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
|
||||
|
@ -370,6 +460,7 @@ NSString * const NCLocalNotificationJoinChatNotification = @"NCLocalN
|
|||
case kNCLocalNotificationTypeMissedCall:
|
||||
case kNCLocalNotificationTypeCancelledCall:
|
||||
case kNCLocalNotificationTypeFailedSendChat:
|
||||
case kNCLocalNotificationTypeChatNotification:
|
||||
{
|
||||
[[NCUserInterfaceController sharedInstance] presentChatForLocalNotification:notificationUserInfo];
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ typedef NS_ENUM(NSInteger, NCPushNotificationType) {
|
|||
};
|
||||
|
||||
extern NSString * const kNCPNAppKey;
|
||||
extern NSString * const kNCPNAppIdKey;
|
||||
extern NSString * const kNCPNTypeKey;
|
||||
extern NSString * const kNCPNSubjectKey;
|
||||
extern NSString * const kNCPNIdKey;
|
||||
|
|
|
@ -55,6 +55,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@property BOOL hasContactSyncEnabled;
|
||||
@property BOOL active;
|
||||
@property NSString *lastReceivedConfigurationHash;
|
||||
@property NSInteger lastNotificationId;
|
||||
@property NSString *lastNotificationETag;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -111,14 +111,20 @@
|
|||
}
|
||||
|
||||
foundDecryptableMessage = YES;
|
||||
|
||||
// Update unread notifications counter for push notification account
|
||||
[realm beginWriteTransaction];
|
||||
NSPredicate *query = [NSPredicate predicateWithFormat:@"accountId = %@", account.accountId];
|
||||
TalkAccount *managedAccount = [TalkAccount objectsInRealm:realm withPredicate:query].firstObject;
|
||||
managedAccount.unreadBadgeNumber += 1;
|
||||
managedAccount.unreadNotification = (managedAccount.active) ? NO : YES;
|
||||
[realm commitWriteTransaction];
|
||||
|
||||
[realm transactionWithBlock:^{
|
||||
NSPredicate *query = [NSPredicate predicateWithFormat:@"accountId = %@", account.accountId];
|
||||
TalkAccount *managedAccount = [TalkAccount objectsInRealm:realm withPredicate:query].firstObject;
|
||||
|
||||
// Update unread notifications counter for push notification account
|
||||
managedAccount.unreadBadgeNumber += 1;
|
||||
managedAccount.unreadNotification = (managedAccount.active) ? NO : YES;
|
||||
|
||||
// Make sure we don't accidentally show a notification again, when we check for notifications in the background
|
||||
if (managedAccount.lastNotificationId < pushNotification.notificationId) {
|
||||
managedAccount.lastNotificationId = pushNotification.notificationId;
|
||||
}
|
||||
}];
|
||||
|
||||
// Get the total number of unread notifications
|
||||
NSInteger unreadNotifications = 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче