From 213d154472f34ded87875f2cf53fdb8fbc2abb99 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 22 Jan 2020 15:32:23 +1100 Subject: [PATCH] Fix group chat notifications --- Signal/src/AppDelegate.m | 82 +++++++++++++++---- .../Public Chat/LokiPublicChatPoller.swift | 10 ++- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index d267e0138..2e117db37 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -1097,12 +1097,25 @@ static NSTimeInterval launchStartedAt; } [LKLogger print:@"[Loki] Silent push notification received; fetching messages."]; - __block AnyPromise *job = [AppEnvironment.shared.messageFetcherJob run].then(^{ - job = nil; + + __block AnyPromise *fetchMessagesPromise = [AppEnvironment.shared.messageFetcherJob run].then(^{ + fetchMessagesPromise = nil; }).catch(^{ - job = nil; + fetchMessagesPromise = nil; }); - [job retainUntilComplete]; + [fetchMessagesPromise retainUntilComplete]; + + __block NSDictionary *publicChats; + [OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + publicChats = [LKDatabaseUtilities getAllPublicChats:transaction]; + }]; + for (LKPublicChat *publicChat in publicChats) { + if (![publicChat isKindOfClass:LKPublicChat.class]) { continue; } // For some reason publicChat is sometimes a base 64 encoded string... + LKPublicChatPoller *poller = [[LKPublicChatPoller alloc] initForPublicChat:publicChat]; + [poller stop]; + AnyPromise *fetchGroupMessagesPromise = [poller pollForNewMessages]; + [fetchGroupMessagesPromise retainUntilComplete]; + } } - (void)application:(UIApplication *)application @@ -1120,14 +1133,35 @@ static NSTimeInterval launchStartedAt; } [LKLogger print:@"[Loki] Silent push notification received; fetching messages."]; - __block AnyPromise *job = [AppEnvironment.shared.messageFetcherJob run].then(^{ - completionHandler(UIBackgroundFetchResultNewData); - job = nil; + + NSMutableArray *promises = [NSMutableArray new]; + + __block AnyPromise *fetchMessagesPromise = [AppEnvironment.shared.messageFetcherJob run].then(^{ + fetchMessagesPromise = nil; }).catch(^{ + fetchMessagesPromise = nil; + }); + [promises addObject:fetchMessagesPromise]; + [fetchMessagesPromise retainUntilComplete]; + + __block NSDictionary *publicChats; + [OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + publicChats = [LKDatabaseUtilities getAllPublicChats:transaction]; + }]; + for (LKPublicChat *publicChat in publicChats) { + if (![publicChat isKindOfClass:LKPublicChat.class]) { continue; } // For some reason publicChat is sometimes a base 64 encoded string... + LKPublicChatPoller *poller = [[LKPublicChatPoller alloc] initForPublicChat:publicChat]; + [poller stop]; + AnyPromise *fetchGroupMessagesPromise = [poller pollForNewMessages]; + [promises addObject:fetchGroupMessagesPromise]; + [fetchGroupMessagesPromise retainUntilComplete]; + } + + PMKJoin(promises).then(^(id results) { + completionHandler(UIBackgroundFetchResultNewData); + }).catch(^(id error) { completionHandler(UIBackgroundFetchResultFailed); - job = nil; }); - [job retainUntilComplete]; } - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { @@ -1229,14 +1263,34 @@ static NSTimeInterval launchStartedAt; NSLog(@"[Loki] Performing background fetch."); [LKAnalytics.shared track:@"Performed Background Fetch"]; [AppReadiness runNowOrWhenAppDidBecomeReady:^{ - __block AnyPromise *job = [AppEnvironment.shared.messageFetcherJob run].then(^{ - completionHandler(UIBackgroundFetchResultNewData); - job = nil; + NSMutableArray *promises = [NSMutableArray new]; + + __block AnyPromise *fetchMessagesPromise = [AppEnvironment.shared.messageFetcherJob run].then(^{ + fetchMessagesPromise = nil; }).catch(^{ + fetchMessagesPromise = nil; + }); + [promises addObject:fetchMessagesPromise]; + [fetchMessagesPromise retainUntilComplete]; + + __block NSDictionary *publicChats; + [OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + publicChats = [LKDatabaseUtilities getAllPublicChats:transaction]; + }]; + for (LKPublicChat *publicChat in publicChats) { + if (![publicChat isKindOfClass:LKPublicChat.class]) { continue; } // For some reason publicChat is sometimes a base 64 encoded string... + LKPublicChatPoller *poller = [[LKPublicChatPoller alloc] initForPublicChat:publicChat]; + [poller stop]; + AnyPromise *fetchGroupMessagesPromise = [poller pollForNewMessages]; + [promises addObject:fetchGroupMessagesPromise]; + [fetchGroupMessagesPromise retainUntilComplete]; + } + + PMKJoin(promises).then(^(id results) { + completionHandler(UIBackgroundFetchResultNewData); + }).catch(^(id error) { completionHandler(UIBackgroundFetchResultFailed); - job = nil; }); - [job retainUntilComplete]; }]; } diff --git a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift index ea171ec65..f7bc5e79f 100644 --- a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift @@ -1,3 +1,4 @@ +import PromiseKit // TODO: Move away from polling @@ -47,10 +48,15 @@ public final class LokiPublicChatPoller : NSObject { } // MARK: Polling - private func pollForNewMessages() { + @objc(pollForNewMessages) + public func objc_pollForNewMessages() -> AnyPromise { + AnyPromise.from(pollForNewMessages()) + } + + public func pollForNewMessages() -> Promise { let publicChat = self.publicChat let userHexEncodedPublicKey = self.userHexEncodedPublicKey - let _ = LokiPublicChatAPI.getMessages(for: publicChat.channel, on: publicChat.server).done(on: DispatchQueue.global()) { messages in + return LokiPublicChatAPI.getMessages(for: publicChat.channel, on: publicChat.server).done(on: DispatchQueue.global()) { messages in let uniqueHexEncodedPublicKeys = Set(messages.map { $0.hexEncodedPublicKey }) func proceed() { let storage = OWSPrimaryStorage.shared()