@@ -57,6 +57,7 @@ LeanplumMessageMatchResult LeanplumMessageMatchResultMake(BOOL matchedTrigger, B
5757BOOL swizzledApplicationDidReceiveRemoteNotificationWithCompletionHandler = NO ;
5858BOOL swizzledApplicationDidReceiveLocalNotification = NO ;
5959BOOL swizzledUserNotificationCenterDidReceiveNotificationResponseWithCompletionHandler = NO ;
60+ BOOL swizzledUserNotificationCenterWillPresentNotificationWithCompletionHandler = NO ;
6061
6162@implementation NSObject (LeanplumExtension)
6263
@@ -166,9 +167,10 @@ - (void)leanplum_application:(UIApplication *)application
166167#pragma clang diagnostic push
167168#pragma clang diagnostic ignored "-Wstrict-prototypes"
168169- (void )leanplum_userNotificationCenter : (UNUserNotificationCenter *)center
169- didReceiveNotificationResponse : (UNNotificationResponse *)response
170- withCompletionHandler : (void (^)())completionHandler
171- API_AVAILABLE(ios(10.0 )) API_AVAILABLE (ios(10.0 )){
170+ didReceiveNotificationResponse : (UNNotificationResponse *)response
171+ withCompletionHandler : (void (^)())completionHandler
172+ API_AVAILABLE(ios(10.0 ))
173+ {
172174
173175 LPLog (LPDebug, @" Called swizzled didReceiveNotificationResponse:withCompletionHandler" );
174176
@@ -185,6 +187,27 @@ - (void)leanplum_userNotificationCenter:(UNUserNotificationCenter *)center
185187
186188 [[LPActionManager sharedManager ] didReceiveNotificationResponse: response withCompletionHandler: completionHandler];
187189}
190+
191+ -(void )leanplum_userNotificationCenter : (UNUserNotificationCenter *)center
192+ willPresentNotification : (UNNotification *)notification
193+ withCompletionHandler : (void (^)(UNNotificationPresentationOptions options))completionHandler
194+ API_AVAILABLE(ios(10.0 ))
195+ {
196+ LPLog (LPDebug, @" Called swizzled willPresentNotification:withCompletionHandler" );
197+
198+ // Call overridden method.
199+ SEL selector = @selector (leanplum_userNotificationCenter:willPresentNotification:withCompletionHandler: );
200+
201+ if (swizzledUserNotificationCenterWillPresentNotificationWithCompletionHandler &&
202+ [self respondsToSelector: selector]) {
203+ [self leanplum_userNotificationCenter: center
204+ willPresentNotification: notification
205+ withCompletionHandler: completionHandler];
206+ }
207+
208+ [[LPActionManager sharedManager ] willPresentNotification: notification withCompletionHandler: completionHandler];
209+ }
210+
188211#pragma clang diagnostic pop
189212
190213- (void )leanplum_application : (UIApplication *)application
@@ -494,6 +517,8 @@ + (BOOL)areActionsEmbedded:(NSDictionary *)userInfo
494517 userInfo[LP_KEY_PUSH_CUSTOM_ACTIONS] != nil ;
495518}
496519
520+ #pragma mark - Push Notifications - Handlers
521+
497522// Handles the notification.
498523// Makes sure the data is loaded, and then displays the notification.
499524- (void )handleNotification : (NSDictionary *)userInfo
@@ -529,6 +554,80 @@ - (void)handleNotification:(NSDictionary *)userInfo
529554 }];
530555}
531556
557+
558+ // Will be called when user taps on notification from status bar iff UNUserNotificationCenterDelegate is implemented in UIApplicationDelegate.
559+ // We need to check first whether the action is muted, and depending on it show or silence the action.
560+ - (void )handleNotificationResponse : (NSDictionary *)userInfo
561+ completionHandler : (LeanplumFetchCompletionBlock)completionHandler
562+ {
563+ NSString *messageId = [LPActionManager messageIdFromUserInfo: userInfo];
564+ if (messageId == nil ) {
565+ return ;
566+ }
567+
568+ void (^onContent)(void ) = ^{
569+ if (completionHandler) {
570+ completionHandler (UIBackgroundFetchResultNewData);
571+ }
572+ BOOL hasAlert = userInfo[@" aps" ][@" alert" ] != nil ;
573+ if (hasAlert) {
574+ [self maybePerformNotificationActions: userInfo action: nil active: NO ];
575+ }
576+ };
577+
578+ if (!userInfo[LP_KEY_PUSH_MUTE_IN_APP] && !userInfo[LP_KEY_PUSH_NO_ACTION_MUTE]) {
579+ [Leanplum onStartIssued: ^() {
580+ if ([LPActionManager areActionsEmbedded: userInfo]) {
581+ onContent ();
582+ } else {
583+ [self requireMessageContent: messageId withCompletionBlock: onContent];
584+ }
585+ }];
586+ } else {
587+ if (messageId && completionHandler) {
588+ completionHandler (UIBackgroundFetchResultNoData);
589+ }
590+ }
591+ }
592+
593+ // Will be called when user receives notification and app is in foreground iff UNUserNotificationCenterDelegate is implemented in UIApplicationDelegate.
594+ // We need to check first whether the action is muted, and depending on it show or silence the action.
595+ - (void )handleWillPresentNotification : (NSDictionary *)userInfo
596+ withCompletionHandler : (void (^)(UNNotificationPresentationOptions options))completionHandler API_AVAILABLE(ios(10.0 ))
597+
598+ {
599+ NSString *messageId = [LPActionManager messageIdFromUserInfo: userInfo];
600+ if (messageId == nil ) {
601+ return ;
602+ }
603+
604+ void (^onContent)(void ) = ^{
605+ if (completionHandler) {
606+ completionHandler (UNNotificationPresentationOptionNone );
607+ }
608+ BOOL hasAlert = userInfo[@" aps" ][@" alert" ] != nil ;
609+ if (hasAlert) {
610+ [self maybePerformNotificationActions: userInfo action: nil active: YES ];
611+ }
612+ };
613+
614+ if (!userInfo[LP_KEY_PUSH_MUTE_IN_APP] && !userInfo[LP_KEY_PUSH_NO_ACTION_MUTE]) {
615+ [Leanplum onStartIssued: ^() {
616+ if ([LPActionManager areActionsEmbedded: userInfo]) {
617+ onContent ();
618+ } else {
619+ [self requireMessageContent: messageId withCompletionBlock: onContent];
620+ }
621+ }];
622+ } else {
623+ if (messageId && completionHandler) {
624+ completionHandler (UNNotificationPresentationOptionNone );
625+ }
626+ }
627+ }
628+
629+ #pragma mark - Push Notifications AppDelegate
630+
532631- (void )didReceiveRemoteNotification : (NSDictionary *)userInfo
533632{
534633 [self didReceiveRemoteNotification: userInfo fetchCompletionHandler: nil ];
@@ -571,6 +670,19 @@ - (void)didReceiveRemoteNotification:(NSDictionary *)userInfo
571670 }
572671}
573672
673+ #pragma mark - Push Notifications UNNotificationFramework
674+
675+ - (void )willPresentNotification : (UNNotification *)notification
676+ withCompletionHandler : (void (^)(UNNotificationPresentationOptions options))completionHandler
677+ {
678+ LP_TRY
679+ // this will be called iff app is active and in foreground visible to the user.
680+ // we will have to check whether we gonna show the action or not.
681+ NSDictionary * userInfo = [[[notification request ] content ] userInfo ];
682+ [self handleWillPresentNotification: userInfo withCompletionHandler: completionHandler];
683+ LP_END_TRY
684+ }
685+
574686- (void )didReceiveNotificationResponse : (UNNotificationResponse *)response withCompletionHandler : (void (^)(void ))completionHandler
575687{
576688 NSDictionary *userInfo = response.notification .request .content .userInfo ;
@@ -586,9 +698,8 @@ - (void)didReceiveNotificationResponse:(UNNotificationResponse *)response withCo
586698 // explicitly.
587699 if (!state.calledHandleNotification ) {
588700 LP_TRY
589- [self didReceiveRemoteNotification: userInfo
590- withAction: nil
591- fetchCompletionHandler: leanplumCompletionHandler];
701+ [self handleNotificationResponse: userInfo
702+ completionHandler: leanplumCompletionHandler];
592703 LP_END_TRY
593704 }
594705 state.calledHandleNotification = NO ;
@@ -686,21 +797,34 @@ + (void)swizzleAppMethods
686797 Method userNotificationCenterDidReceiveNotificationResponseWithCompletionHandlerMethod =
687798 class_getInstanceMethod ([appDelegate class ],
688799 userNotificationCenterDidReceiveNotificationResponseWithCompletionHandlerSelector);
689- void (^swizzleUserNotificationDidReceiveNotificationResponseWithCompletionHandler)(void ) =^{
800+ void (^swizzleUserNotificationDidReceiveNotificationResponseWithCompletionHandler)(void ) = ^{
690801 swizzledUserNotificationCenterDidReceiveNotificationResponseWithCompletionHandler =
691802 [LPSwizzle hookInto: userNotificationCenterDidReceiveNotificationResponseWithCompletionHandlerSelector
692803 withSelector: @selector (leanplum_userNotificationCenter:
693804 didReceiveNotificationResponse:
694805 withCompletionHandler: )
695806 forObject: [appDelegate class ]];
696807 };
808+
809+ SEL userNotificationCenterWillPresentNotificationWithCompletionHandlerSelector = @selector (userNotificationCenter:
810+ willPresentNotification:
811+ withCompletionHandler: );
812+ Method userNotificationCenterWillPresentNotificationWithCompletionHandlerMethod = class_getInstanceMethod ([appDelegate class ],
813+ userNotificationCenterWillPresentNotificationWithCompletionHandlerSelector);
814+ void (^swizzleUserNotificationWillPresentNotificationWithCompletionHandler)(void ) = ^{
815+ swizzledUserNotificationCenterWillPresentNotificationWithCompletionHandler = [LPSwizzle
816+ hookInto: userNotificationCenterWillPresentNotificationWithCompletionHandlerSelector
817+ withSelector: @selector (leanplum_userNotificationCenter:willPresentNotification:withCompletionHandler: )
818+ forObject: [appDelegate class ]];
819+ };
697820
698821 if (!applicationDidReceiveRemoteNotificationMethod
699822 && !applicationDidReceiveRemoteNotificationCompletionHandlerMethod) {
700823 swizzleApplicationDidReceiveRemoteNotification ();
701824 swizzleApplicationDidReceiveRemoteNotificationFetchCompletionHandler ();
702825 if (NSClassFromString (@" UNUserNotificationCenter" )) {
703826 swizzleUserNotificationDidReceiveNotificationResponseWithCompletionHandler ();
827+ swizzleUserNotificationWillPresentNotificationWithCompletionHandler ();
704828 }
705829 } else {
706830 if (applicationDidReceiveRemoteNotificationMethod) {
@@ -713,6 +837,9 @@ + (void)swizzleAppMethods
713837 if (userNotificationCenterDidReceiveNotificationResponseWithCompletionHandlerMethod) {
714838 swizzleUserNotificationDidReceiveNotificationResponseWithCompletionHandler ();
715839 }
840+ if (userNotificationCenterWillPresentNotificationWithCompletionHandlerMethod) {
841+ swizzleUserNotificationWillPresentNotificationWithCompletionHandler ();
842+ }
716843 }
717844 }
718845
0 commit comments