Page MenuHomePhabricator

D6067.id20216.diff
No OneTemporary

D6067.id20216.diff

diff --git a/native/ios/Comm/CommIOSNotifications/CommIOSNotifications.mm b/native/ios/Comm/CommIOSNotifications/CommIOSNotifications.mm
--- a/native/ios/Comm/CommIOSNotifications/CommIOSNotifications.mm
+++ b/native/ios/Comm/CommIOSNotifications/CommIOSNotifications.mm
@@ -84,6 +84,124 @@
localNotification ? localNotification.userInfo : nil;
}
+/*
+ Public methods
+*/
++ (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken {
+ NSString *tokenRepresentation = [deviceToken isKindOfClass:[NSString class]]
+ ? deviceToken
+ : [self deviceTokenToString:deviceToken];
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:CommIOSNotificationsRegistered
+ object:self
+ userInfo:@{@"deviceToken" : tokenRepresentation}];
+}
+
++ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:CommIOSNotificationsRegistrationFailed
+ object:self
+ userInfo:@{
+ @"code" : [NSNumber numberWithInteger:error.code],
+ @"domain" : error.domain,
+ @"localizedDescription" : error.localizedDescription
+ }];
+}
+
++ (void)didReceiveRemoteNotification:(NSDictionary *)notification
+ fetchCompletionHandler:
+ (void (^)(UIBackgroundFetchResult))completionHandler {
+ NSDictionary *notifInfo = @{
+ @"notification" : notification,
+ @"completionHandler" : completionHandler
+ };
+ UIApplicationState state = [UIApplication sharedApplication].applicationState;
+
+ if ([CommIOSNotificationsBridgeQueue sharedInstance].jsIsReady == YES) {
+ // JS thread is ready, push the notification to the bridge
+
+ if (state == UIApplicationStateActive) {
+ // Notification received foreground
+ [self didReceiveNotificationOnForegroundState:notifInfo];
+ } else if (state == UIApplicationStateInactive) {
+ // Notification opened
+ [self didNotificationOpen:notifInfo];
+ } else {
+ // Notification received background
+ [self didReceiveNotificationOnBackgroundState:notifInfo];
+ }
+ } else {
+ // JS thread is not ready - store it in the native notifications queue
+ [[CommIOSNotificationsBridgeQueue sharedInstance]
+ postNotification:notifInfo];
+ }
+}
+
++ (void)didReceiveLocalNotification:(UILocalNotification *)notification {
+ UIApplicationState state = [UIApplication sharedApplication].applicationState;
+
+ NSMutableDictionary *newUserInfo = notification.userInfo.mutableCopy;
+ [newUserInfo removeObjectForKey:@"__id"];
+ notification.userInfo = newUserInfo;
+
+ NSDictionary *notifInfo = @{@"notification" : notification.userInfo};
+ if (state == UIApplicationStateActive) {
+ [self didReceiveNotificationOnForegroundState:notifInfo];
+ } else if (state == UIApplicationStateInactive) {
+ NSString *notificationId =
+ [notification.userInfo objectForKey:@"notificationId"];
+ if (notificationId) {
+ [self clearNotificationFromNotificationsCenter:notificationId
+ completionHandler:nil];
+ }
+ [self didNotificationOpen:notifInfo];
+ }
+}
+
++ (void)clearNotificationFromNotificationsCenter:(NSString *)notificationId
+ completionHandler:
+ (void (^)(UIBackgroundFetchResult))
+ completionHandler {
+ if ([UNUserNotificationCenter class]) {
+ [[UNUserNotificationCenter currentNotificationCenter]
+ getDeliveredNotificationsWithCompletionHandler:^(
+ NSArray<UNNotification *> *_Nonnull notifications) {
+ for (UNNotification *notif in notifications) {
+ if ([notificationId
+ isEqual:notif.request.content.userInfo[@"id"]]) {
+ NSArray *identifiers =
+ [NSArray arrayWithObjects:notif.request.identifier, nil];
+ [[UNUserNotificationCenter currentNotificationCenter]
+ removeDeliveredNotificationsWithIdentifiers:identifiers];
+ }
+ }
+ if (completionHandler) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ completionHandler(UIBackgroundFetchResultNewData);
+ });
+ }
+ }];
+ return;
+ }
+
+ NSString *notificationKey =
+ [self buildNotificationKeyfromNotification:notificationId];
+ NSData *data =
+ [[NSUserDefaults standardUserDefaults] objectForKey:notificationKey];
+ if (data) {
+ UILocalNotification *notification =
+ [NSKeyedUnarchiver unarchiveObjectWithData:data];
+
+ // delete the notification
+ [[UIApplication sharedApplication] cancelLocalNotification:notification];
+ [[NSUserDefaults standardUserDefaults] removeObjectForKey:notificationKey];
+
+ NSLog(@"Local notification removed: %@", notificationKey);
+
+ return;
+ }
+}
+
/*
JavaScript Events
*/
@@ -133,4 +251,93 @@
body:notification.userInfo];
}
+/*
+ Notifications Handlers
+*/
++ (void)didReceiveNotificationOnForegroundState:(NSDictionary *)notifInfo {
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:CommIOSNotificationsReceivedForeground
+ object:self
+ userInfo:notifInfo];
+}
+
++ (void)didReceiveNotificationOnBackgroundState:(NSDictionary *)notifInfo {
+ NSDictionary *notification = notifInfo[@"notification"];
+
+ NSDictionary *managedAps = [notification objectForKey:@"managedAps"];
+ NSDictionary *alert = [managedAps objectForKey:@"alert"];
+ NSString *action = [managedAps objectForKey:@"action"];
+ NSString *notificationId = [managedAps objectForKey:@"notificationId"];
+
+ if (action &&
+ ([action isEqualToString:CommIOSNotificationsCreateAction] &&
+ notificationId && alert)) {
+ // create notification
+ [self dispatchLocalNotificationFromNotification:notification];
+ }
+
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:CommIOSNotificationsReceivedBackground
+ object:self
+ userInfo:notifInfo];
+}
+
++ (void)didNotificationOpen:(NSDictionary *)notifInfo {
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:CommIOSNotificationsOpened
+ object:self
+ userInfo:notifInfo];
+}
+
+/*
+ Helper methods
+*/
++ (void)dispatchLocalNotificationFromNotification:(NSDictionary *)notification {
+ NSDictionary *managedAps = [notification objectForKey:@"managedAps"];
+ NSDictionary *alert = [managedAps objectForKey:@"alert"];
+ NSString *action = [managedAps objectForKey:@"action"];
+ NSString *notificationId = [managedAps objectForKey:@"notificationId"];
+
+ if ([action isEqualToString:CommIOSNotificationsCreateAction] &&
+ notificationId && alert) {
+
+ // trigger new client push notification
+ UILocalNotification *note = [UILocalNotification new];
+ note.alertTitle = [alert objectForKey:@"title"];
+ note.alertBody = [alert objectForKey:@"body"];
+ note.userInfo = notification;
+ note.soundName = [managedAps objectForKey:@"sound"];
+ note.category = [managedAps objectForKey:@"category"];
+
+ [[UIApplication sharedApplication] presentLocalNotificationNow:note];
+
+ // Serialize it and store so we can delete it later
+ NSData *data = [NSKeyedArchiver archivedDataWithRootObject:note];
+ NSString *notificationKey =
+ [self buildNotificationKeyfromNotification:notificationId];
+ [[NSUserDefaults standardUserDefaults] setObject:data
+ forKey:notificationKey];
+ [[NSUserDefaults standardUserDefaults] synchronize];
+
+ NSLog(@"Local notification was triggered: %@", notificationKey);
+ }
+}
+
++ (NSString *)buildNotificationKeyfromNotification:(NSString *)notificationId {
+ return [NSString stringWithFormat:@"%@.%@",
+ [[NSBundle mainBundle] bundleIdentifier],
+ notificationId];
+}
+
++ (NSString *)deviceTokenToString:(NSData *)deviceToken {
+ NSMutableString *result = [NSMutableString string];
+ NSUInteger deviceTokenLength = deviceToken.length;
+ const unsigned char *bytes = (const unsigned char *)deviceToken.bytes;
+ for (NSUInteger i = 0; i < deviceTokenLength; i++) {
+ [result appendFormat:@"%02x", bytes[i]];
+ }
+
+ return [result copy];
+}
+
@end

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 16, 12:26 PM (20 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2497830
Default Alt Text
D6067.id20216.diff (8 KB)

Event Timeline