Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3249135
D6067.id20216.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
D6067.id20216.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D6067: Implement native public notifications API
Attached
Detach File
Event Timeline
Log In to Comment