From b5c3642490fee267bde1ccaf1742290362c3539a Mon Sep 17 00:00:00 2001 From: Nan Date: Wed, 25 Oct 2023 15:07:15 -0700 Subject: [PATCH 1/2] Foward notif opens to the legacy app selector for non OneSignal notifs Based on https://github.com/OneSignal/OneSignal-iOS-SDK/pull/1131 --- ...otificationCenter+OneSignalNotifications.m | 51 ++++++++----------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UNUserNotificationCenter+OneSignalNotifications.m b/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UNUserNotificationCenter+OneSignalNotifications.m index 7e9441b49..14bb1bbc1 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UNUserNotificationCenter+OneSignalNotifications.m +++ b/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UNUserNotificationCenter+OneSignalNotifications.m @@ -308,37 +308,13 @@ void finishProcessingNotification(UNNotification *notification, completionHandler(completionHandlerOptions); } -// Apple's docs - Called to let your app know which action was selected by the user for a given notification. -- (void)onesignalUserNotificationCenter:(UNUserNotificationCenter *)center - didReceiveNotificationResponse:(UNNotificationResponse *)response - withCompletionHandler:(void(^)(void))completionHandler { - [OneSignalNotificationsUNUserNotificationCenter traceCall:@"onesignalUserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:"]; - // return if the user has not granted privacy permissions or if not a OneSignal payload - if ([OSPrivacyConsentController shouldLogMissingPrivacyConsentErrorWithMethodName:nil] || ![OneSignalCoreHelper isOneSignalPayload:response.notification.request.content.userInfo]) { - SwizzlingForwarder *forwarder = [[SwizzlingForwarder alloc] - initWithTarget:self - withYourSelector:@selector( - onesignalUserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: - ) - withOriginalSelector:@selector( - userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: - ) - ]; - if (forwarder.hasReceiver) { - [forwarder invokeWithArgs:@[center, response, completionHandler]]; - } else { - completionHandler(); - } - return; - } - - [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:@"onesignalUserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: Fired!"]; - - [OneSignalNotificationsUNUserNotificationCenter processiOS10Open:response]; - - // Call orginal selector if one was set. ++ (void)forwardReceivedNotificationResponseWithCenter:(UNUserNotificationCenter *)center + didReceiveNotificationResponse:(UNNotificationResponse *)response + OneSignalCenter:(id)instance + withCompletionHandler:(void(^)(void))completionHandler { + // Call original selector if one was set. SwizzlingForwarder *forwarder = [[SwizzlingForwarder alloc] - initWithTarget:self + initWithTarget:instance withYourSelector:@selector( onesignalUserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: ) @@ -365,6 +341,21 @@ - (void)onesignalUserNotificationCenter:(UNUserNotificationCenter *)center completionHandler(); } +// Apple's docs - Called to let your app know which action was selected by the user for a given notification. +- (void)onesignalUserNotificationCenter:(UNUserNotificationCenter *)center + didReceiveNotificationResponse:(UNNotificationResponse *)response + withCompletionHandler:(void(^)(void))completionHandler { + [OneSignalNotificationsUNUserNotificationCenter traceCall:@"onesignalUserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:"]; + + if (![OSPrivacyConsentController shouldLogMissingPrivacyConsentErrorWithMethodName:nil] && [OneSignalCoreHelper isOneSignalPayload:response.notification.request.content.userInfo]) { + [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:@"onesignalUserNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: Fired!"]; + + [OneSignalNotificationsUNUserNotificationCenter processiOS10Open:response]; + } + + [OneSignalNotificationsUNUserNotificationCenter forwardReceivedNotificationResponseWithCenter:center didReceiveNotificationResponse:response OneSignalCenter:self withCompletionHandler:completionHandler]; +} + + (BOOL)isDismissEvent:(UNNotificationResponse *)response { return [@"com.apple.UNNotificationDismissActionIdentifier" isEqual:response.actionIdentifier]; } From 35c4875bcf6cb3f989943d542fcfc60866c4514c Mon Sep 17 00:00:00 2001 From: Nan Date: Wed, 25 Oct 2023 15:12:29 -0700 Subject: [PATCH 2/2] Unit tests for notification open forwarding to legacy selector Cherry picked from https://github.com/OneSignal/OneSignal-iOS-SDK/pull/1131 --- .../UIApplicationDelegateSwizzlingTests.m | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/iOS_SDK/OneSignalSDK/UnitTests/UIApplicationDelegateSwizzlingTests.m b/iOS_SDK/OneSignalSDK/UnitTests/UIApplicationDelegateSwizzlingTests.m index 9f1cc9360..1603f0e10 100644 --- a/iOS_SDK/OneSignalSDK/UnitTests/UIApplicationDelegateSwizzlingTests.m +++ b/iOS_SDK/OneSignalSDK/UnitTests/UIApplicationDelegateSwizzlingTests.m @@ -562,6 +562,47 @@ - (void)testCallsDepercatedDidReceiveRemoteNotification { XCTAssertTrue(myAppDelegate->selectorCalled); } +- (UNNotificationResponse*)createOneSignalNotificationResponse { + id userInfo = @{@"custom": + @{ @"i": @"b2f7f966-d8cc-11e4-bed1-df8f05be55ba" } + }; + + return [UnitTestCommonMethods createBasiciOSNotificationResponseWithPayload:userInfo]; +} + +- (UNNotificationResponse*)createNonOneSignalNotificationResponse { + return [UnitTestCommonMethods createBasiciOSNotificationResponseWithPayload:@{}]; +} + +- (void)testNotificationOpenForwardsToLegacySelector { + AppDelegateForExistingSelectorsTest* myAppDelegate = [AppDelegateForExistingSelectorsTest new]; + UIApplication.sharedApplication.delegate = myAppDelegate; + + id notifResponse = [self createOneSignalNotificationResponse]; + UNUserNotificationCenter *notifCenter = [UNUserNotificationCenter currentNotificationCenter]; + id notifCenterDelegate = notifCenter.delegate; + // UNUserNotificationCenterDelegate method iOS 10 calls directly when a notification is opened. + [notifCenterDelegate userNotificationCenter:notifCenter didReceiveNotificationResponse:notifResponse withCompletionHandler:^() {}]; + XCTAssertTrue([myAppDelegate->selectorCallsDict + objectForKey:NSStringFromSelector( + @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:) + ) + ]); + XCTAssertEqual([OneSignalAppDelegateOverrider callCountForSelector:@"oneSignalReceiveRemoteNotification:UserInfo:fetchCompletionHandler:"], 1); + + notifResponse = [self createNonOneSignalNotificationResponse]; + notifCenter = [UNUserNotificationCenter currentNotificationCenter]; + notifCenterDelegate = notifCenter.delegate; + // UNUserNotificationCenterDelegate method iOS 10 calls directly when a notification is opened. + [notifCenterDelegate userNotificationCenter:notifCenter didReceiveNotificationResponse:notifResponse withCompletionHandler:^() {}]; + XCTAssertTrue([myAppDelegate->selectorCallsDict + objectForKey:NSStringFromSelector( + @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:) + ) + ]); + XCTAssertEqual([OneSignalAppDelegateOverrider callCountForSelector:@"oneSignalReceiveRemoteNotification:UserInfo:fetchCompletionHandler:"], 2); +} + - (void)testAppDelegateInheritsFromBaseMissingSelectors { id myAppDelegate = [AppDelegateInheritsFromBaseMissingSelectorsTest new]; UIApplication.sharedApplication.delegate = myAppDelegate;