From abbae87d71ca63c4b12bda2fb5cd679cfd85eee9 Mon Sep 17 00:00:00 2001 From: abhishekksanghvi1989 Date: Thu, 7 Nov 2019 15:51:16 +0530 Subject: [PATCH] support inline reply in ios pushnotification --- src/ios/AppDelegate+notification.m | 120 +++++++++++++++++++++++++++++ src/ios/PushPlugin.h | 2 +- src/ios/PushPlugin.m | 52 ++++++++++++- 3 files changed, 170 insertions(+), 4 deletions(-) diff --git a/src/ios/AppDelegate+notification.m b/src/ios/AppDelegate+notification.m index b04c47687..3ee631fa8 100644 --- a/src/ios/AppDelegate+notification.m +++ b/src/ios/AppDelegate+notification.m @@ -71,8 +71,19 @@ - (AppDelegate *)pushPluginSwizzledInit - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; [pushHandler didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; + + [[NSNotificationCenter defaultCenter]addObserver:self + selector:@selector(inLineNotificationHandler:) + name:@"inlinecallback" + object:nil]; + + [[NSNotificationCenter defaultCenter]addObserver:self + selector:@selector(handleConfirmDeclineNotification:) + name:@"confirmcallback" + object:nil]; } + - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; [pushHandler didFailToRegisterForRemoteNotificationsWithError:error]; @@ -126,10 +137,15 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N NSLog(@"just put it in the shade"); //save it for later self.launchNotification = userInfo; + completionHandler(UIBackgroundFetchResultNewData); } } else { + PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; + pushHandler.notificationMessage = userInfo; + pushHandler.isInline = YES; + [pushHandler notificationReceived]; completionHandler(UIBackgroundFetchResultNoData); } } @@ -258,6 +274,110 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center } } +- (void)inLineNotificationHandler:(NSNotification *)notification { + + NSLog(@"inLineNotificationHandler::::::%@",notification.userInfo); + UNNotificationResponse* response = (UNNotificationResponse *)notification.userInfo; + + NSMutableDictionary *userInfo = [response.notification.request.content.userInfo mutableCopy]; + + // set user text for plugin. + UNTextInputNotificationResponse * textResponse = (UNTextInputNotificationResponse *) response; + if (textResponse.userText != nil){ + NSLog(@"textResponse:::::: %@ %@",textResponse, textResponse.userText); + [userInfo setObject:textResponse.userText forKey:@"userText"]; + } + + [userInfo setObject:response.actionIdentifier forKey:@"actionCallback"]; + NSLog(@"Push Plugin userInfo %@", userInfo); + + if (UIApplication.sharedApplication.applicationState == UIApplicationStateActive) { + PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; + pushHandler.notificationMessage = userInfo; + pushHandler.isInline = NO; + [pushHandler notificationReceived]; + }else if (UIApplication.sharedApplication.applicationState == UIApplicationStateInactive){ + NSLog(@"coldstart"); + self.launchNotification = response.notification.request.content.userInfo; + self.coldstart = [NSNumber numberWithBool:YES]; + } + else{ + + void (^safeHandler)() = ^(void){ + dispatch_async(dispatch_get_main_queue(), ^{ + // TODO: Handle Callback + }); + }; + + PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; + + if (pushHandler.handlerObj == nil) { + pushHandler.handlerObj = [NSMutableDictionary dictionaryWithCapacity:2]; + } + + id notId = [userInfo objectForKey:@"notId"]; + if (notId != nil) { + NSLog(@"Push Plugin notId %@", notId); + [pushHandler.handlerObj setObject:safeHandler forKey:notId]; + } else { + NSLog(@"Push Plugin notId handler"); + [pushHandler.handlerObj setObject:safeHandler forKey:@"handler"]; + } + + pushHandler.notificationMessage = userInfo; + pushHandler.isInline = NO; + + [pushHandler performSelectorOnMainThread:@selector(notificationReceived) withObject:pushHandler waitUntilDone:NO]; + } +} + +- (void)handleConfirmDeclineNotification:(NSNotification *)notification { + + NSLog(@"inLineNotificationHandler::::::%@",notification.userInfo); + UNNotificationResponse* response = (UNNotificationResponse *)notification.userInfo; + + NSMutableDictionary *userInfo = [response.notification.request.content.userInfo mutableCopy]; + [userInfo setObject:response.actionIdentifier forKey:@"actionCallback"]; + NSLog(@"Push Plugin userInfo %@", userInfo); + + if (UIApplication.sharedApplication.applicationState == UIApplicationStateActive) { + PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; + pushHandler.notificationMessage = userInfo; + pushHandler.isInline = NO; + [pushHandler notificationReceived]; + }else if(UIApplication.sharedApplication.applicationState == UIApplicationStateInactive){ + NSLog(@"coldstart"); + self.launchNotification = response.notification.request.content.userInfo; + self.coldstart = [NSNumber numberWithBool:YES]; + } else { + void (^safeHandler)() = ^(void){ + dispatch_async(dispatch_get_main_queue(), ^{ + // TODO: Handle callback + }); + }; + + PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; + + if (pushHandler.handlerObj == nil) { + pushHandler.handlerObj = [NSMutableDictionary dictionaryWithCapacity:2]; + } + + id notId = [userInfo objectForKey:@"notId"]; + if (notId != nil) { + NSLog(@"Push Plugin notId %@", notId); + [pushHandler.handlerObj setObject:safeHandler forKey:notId]; + } else { + NSLog(@"Push Plugin notId handler"); + [pushHandler.handlerObj setObject:safeHandler forKey:@"handler"]; + } + + pushHandler.notificationMessage = userInfo; + pushHandler.isInline = NO; + + [pushHandler performSelectorOnMainThread:@selector(notificationReceived) withObject:pushHandler waitUntilDone:NO]; + } +} + // The accessors use an Associative Reference since you can't define a iVar in a category // http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocAssociativeReferences.html - (NSMutableArray *)launchNotification diff --git a/src/ios/PushPlugin.h b/src/ios/PushPlugin.h index 4b6ec930a..c35897954 100644 --- a/src/ios/PushPlugin.h +++ b/src/ios/PushPlugin.h @@ -41,7 +41,7 @@ NSMutableDictionary *handlerObj; void (^completionHandler)(UIBackgroundFetchResult); - + NSString *replyCallBack; BOOL ready; } diff --git a/src/ios/PushPlugin.m b/src/ios/PushPlugin.m index 9aca1d0d9..249a0218d 100644 --- a/src/ios/PushPlugin.m +++ b/src/ios/PushPlugin.m @@ -241,19 +241,37 @@ - (void)init:(CDVInvokedUrlCommand*)command; id category = [categoryOptions objectForKey:key]; id yesButton = [category objectForKey:@"yes"]; + UNNotificationAction *yesAction; if (yesButton != nil && [yesButton isKindOfClass:[NSDictionary class]]) { - yesAction = [self createAction: yesButton]; + id isInline = [yesButton objectForKey:@"inline"]; + if (isInline != nil && (([isInline isKindOfClass:[NSString class]] && [isInline isEqualToString:@"true"]) || [isInline boolValue])) { + yesAction = [self createReplyAction: yesButton]; + }else{ + yesAction = [self createAction: yesButton]; + } } id noButton = [category objectForKey:@"no"]; + UNNotificationAction *noAction; if (noButton != nil && [noButton isKindOfClass:[NSDictionary class]]) { - noAction = [self createAction: noButton]; + id isInline = [noButton objectForKey:@"inline"]; + if (isInline != nil && (([isInline isKindOfClass:[NSString class]] && [isInline isEqualToString:@"true"]) || [isInline boolValue])) { + noAction = [self createReplyAction: noButton]; + }else{ + noAction = [self createAction: noButton]; + } } id maybeButton = [category objectForKey:@"maybe"]; + UNNotificationAction *maybeAction; if (maybeButton != nil && [maybeButton isKindOfClass:[NSDictionary class]]) { - maybeAction = [self createAction: maybeButton]; + id isInline = [maybeButton objectForKey:@"inline"]; + if (isInline != nil && (([isInline isKindOfClass:[NSString class]] && [isInline isEqualToString:@"true"]) || [isInline boolValue])) { + maybeAction = [self createReplyAction: maybeButton]; + }else{ + maybeAction = [self createAction: maybeButton]; + } } // Identifier to include in your push payload and local notification @@ -282,6 +300,9 @@ - (void)init:(CDVInvokedUrlCommand*)command; } UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + + [center setDelegate:self]; + [center setNotificationCategories:categories]; [self handleNotificationSettingsWithAuthorizationOptions:[NSNumber numberWithInteger:authorizationOptions]]; @@ -355,6 +376,15 @@ - (UNNotificationAction *)createAction:(NSDictionary *)dictionary { return [UNNotificationAction actionWithIdentifier:identifier title:title options:options]; } +- (UNTextInputNotificationAction *)createReplyAction:(NSDictionary *)dictionary { + replyCallBack = [dictionary objectForKey:@"callback"]; + UNNotificationActionOptions effectiveMode = UNNotificationActionOptionNone; + + UNTextInputNotificationAction *myAction = [UNTextInputNotificationAction actionWithIdentifier:[dictionary objectForKey:@"callback"] title:[dictionary objectForKey:@"title"] options:effectiveMode]; + + return myAction; +} + - (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { if (self.callbackId == nil) { NSLog(@"Unexpected call to didRegisterForRemoteNotificationsWithDeviceToken, ignoring: %@", deviceToken); @@ -488,6 +518,22 @@ - (void)notificationReceived { } } +-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { + + NSLog(@"didReceiveNotificationResponse %@",response); + NSLog(@"response.actionIdentifier %@",response.actionIdentifier); + NSLog(@"replyCallBack %@", replyCallBack); + + //for inline reply notification + if ([response isKindOfClass:[UNTextInputNotificationResponse class]]) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"inlinecallback" object:nil userInfo:response]; + }else { // for confirm and decline notification + [[NSNotificationCenter defaultCenter] postNotificationName:@"confirmcallback" object:nil userInfo:response]; + } + + completionHandler(); +} + - (void)clearNotification:(CDVInvokedUrlCommand *)command { NSNumber *notId = [command.arguments objectAtIndex:0];