Skip to content

Commit

Permalink
fix(ios): deliver payload to frontend handler when app in background
Browse files Browse the repository at this point in the history
  • Loading branch information
erisu committed Feb 4, 2025
1 parent d50a41b commit 53365c6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ The event `notification` will be triggered each time a push notification is rece
| `data.additionalData.foreground` | `boolean` | Whether the notification was received while the app was in the foreground |
| `data.additionalData.coldstart` | `boolean` | Will be `true` if the application is started by clicking on the push notification, `false` if the app is already started. |
| `data.additionalData.dismissed` | `boolean` | Is set to `true` if the notification was dismissed by the user |
| `data.additionalData.applicationState` | `number` | (iOS Only Flag) Contains the application state of the received notification. 0: `UIApplicationStateActive`, 1: `UIApplicationStateInactive`, 2: `UIApplicationStateBackground` |

### Example

Expand Down
32 changes: 25 additions & 7 deletions src/ios/PushPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ - (void)init:(CDVInvokedUrlCommand *)command {
[center setNotificationCategories:[settings categories]];

// If there is a pending startup notification, we will delay to allow JS event handlers to setup
if (self.notificationMessage && !self.isInitialized) {
dispatch_async(dispatch_get_main_queue(), ^{
[self performSelector:@selector(notificationReceived) withObject:nil afterDelay: 0.5];
if (self.notificationMessage) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self notificationReceived:YES];
});
}

Expand Down Expand Up @@ -489,6 +489,10 @@ - (void)didReceiveNotificationResponse:(NSNotification *)notification {
}

- (void)notificationReceived {
[self notificationReceived:NO];
}

- (void)notificationReceived:(BOOL)shouldForceClear {
NSLog(@"[PushPlugin] Notification received");

if (self.notificationMessage && self.callbackId != nil)
Expand All @@ -502,9 +506,7 @@ - (void)notificationReceived {
if ([[mutableNotificationMessage objectForKey:@"actionCallback"] isEqualToString:UNNotificationDefaultActionIdentifier]) {
[mutableNotificationMessage removeObjectForKey:@"actionCallback"];
}
// @todo do not sent applicationState data to front for now. Figure out if we can add
// similar data to the other platforms.
[mutableNotificationMessage removeObjectForKey:@"applicationState"];

self.notificationMessage = [mutableNotificationMessage copy];

for (id key in self.notificationMessage) {
Expand Down Expand Up @@ -567,9 +569,25 @@ - (void)notificationReceived {
[pluginResult setKeepCallbackAsBool:YES];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];

// When application state is inactive, do not clear notificationMessage.
// The init method will trigger when returning to foreground and trigger notification process.
NSNumber *applicationState = self.notificationMessage[@"applicationState"];
if (applicationState && [applicationState isKindOfClass:[NSNumber class]]) {
if ([applicationState integerValue] != UIApplicationStateInactive) {
self.notificationMessage = nil;
}
} else {
// Handle unexpected cases where applicationState is missing or invalid
self.notificationMessage = nil;
}

// Force clear comes from init. This ensure that it will be processed once.
if (shouldForceClear) {
self.notificationMessage = nil;
}

self.coldstart = NO;
self.isForeground = NO;
self.notificationMessage = nil;
}
}

Expand Down

0 comments on commit 53365c6

Please sign in to comment.