diff --git a/native/ios/Comm/AppDelegate.mm b/native/ios/Comm/AppDelegate.mm --- a/native/ios/Comm/AppDelegate.mm +++ b/native/ios/Comm/AppDelegate.mm @@ -58,6 +58,21 @@ NSString *const setUnreadStatusKey = @"setUnreadStatus"; NSString *const threadIDKey = @"threadID"; +NSString *const newMessageInfosNSNotification = + @"app.comm.ns_new_message_infos"; +CFStringRef newMessageInfosDarwinNotification = + CFSTR("app.comm.darwin_new_message_infos"); + +void didReceiveNewMessageInfosDarwinNotification( + CFNotificationCenterRef center, + void *observer, + CFStringRef name, + const void *object, + CFDictionaryRef userInfo) { + [[NSNotificationCenter defaultCenter] + postNotificationName:newMessageInfosNSNotification + object:nil]; +} @interface AppDelegate () < RCTCxxBridgeDelegate, @@ -70,6 +85,7 @@ - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self attemptDatabaseInitialization]; + [self registerForNewMessageInfosNotifications]; return YES; } @@ -77,7 +93,7 @@ didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { RCTAppSetupPrepareApp(application); - [self moveMessagesToDatabase]; + [self moveMessagesToDatabase:NO]; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil]; @@ -303,11 +319,15 @@ }); } -- (void)moveMessagesToDatabase { +- (void)moveMessagesToDatabase:(BOOL)sendBackgroundMessagesInfosToJS { TemporaryMessageStorage *temporaryStorage = [[TemporaryMessageStorage alloc] init]; NSArray *messages = [temporaryStorage readAndClearMessages]; for (NSString *message in messages) { + if (sendBackgroundMessagesInfosToJS) { + [CommIOSNotifications + didReceiveBackgroundMessageInfos:@{@"messageInfos" : message}]; + } std::string messageInfos = std::string([message UTF8String]); comm::GlobalDBSingleton::instance.scheduleOrRun([messageInfos]() mutable { comm::MessageOperationsUtilities::storeMessageInfos(messageInfos); @@ -346,6 +366,26 @@ } } +- (void)didReceiveNewMessageInfosNSNotification:(NSNotification *)notification { + [self moveMessagesToDatabase:YES]; +} + +- (void)registerForNewMessageInfosNotifications { + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(didReceiveNewMessageInfosNSNotification:) + name:newMessageInfosNSNotification + object:nil]; + + CFNotificationCenterAddObserver( + CFNotificationCenterGetDarwinNotifyCenter(), + (__bridge const void *)(self), + didReceiveNewMessageInfosDarwinNotification, + newMessageInfosDarwinNotification, + NULL, + CFNotificationSuspensionBehaviorDeliverImmediately); +} + // Copied from // ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp static ::hermes::vm::RuntimeConfig diff --git a/native/ios/NotificationService/NotificationService.mm b/native/ios/NotificationService/NotificationService.mm --- a/native/ios/NotificationService/NotificationService.mm +++ b/native/ios/NotificationService/NotificationService.mm @@ -6,6 +6,8 @@ // The context for this constant can be found here: // https://linear.app/comm/issue/ENG-3074#comment-bd2f5e28 int64_t const notificationRemovalDelay = (int64_t)(0.1 * NSEC_PER_SEC); +CFStringRef newMessageInfosDarwinNotification = + CFSTR("app.comm.darwin_new_message_infos"); @interface NotificationService () @@ -33,7 +35,7 @@ self.contentHandler([[UNNotificationContent alloc] init]); return; } - + [self sendNewMessageInfosNotification]; // TODO modify self.bestAttemptContent here self.contentHandler(self.bestAttemptContent); @@ -120,4 +122,13 @@ [payload[backgroundNotificationTypeKey] isEqualToString:@"CLEAR"]; } +- (void)sendNewMessageInfosNotification { + CFNotificationCenterPostNotification( + CFNotificationCenterGetDarwinNotifyCenter(), + newMessageInfosDarwinNotification, + (__bridge const void *)(self), + nil, + TRUE); +} + @end diff --git a/native/push/push-handler.react.js b/native/push/push-handler.react.js --- a/native/push/push-handler.react.js +++ b/native/push/push-handler.react.js @@ -147,6 +147,10 @@ 'notificationOpened', this.iosNotificationOpened, ), + commIOSNotificationsEventEmitter.addListener( + 'notificationReceivedBackground', + backgroundData => this.saveMessageInfos(backgroundData?.messageInfos), + ), ); } else if (Platform.OS === 'android') { CommAndroidNotifications.createChannel(