From dbcd7530419b7b0d815664285081cb25a769567e Mon Sep 17 00:00:00 2001 From: emawby Date: Wed, 26 Jul 2023 15:57:35 -0700 Subject: [PATCH] Do not swizzle a subclass of an already swizzled class Adding unit test for swizzling subclass Adding subClass swizzling check to UNUserNotificationCenter Don't swizzle subclass if we have already swizzled its super --- ...plicationDelegate+OneSignalNotifications.m | 19 ++++++++++++++++++- ...otificationCenter+OneSignalNotifications.m | 3 ++- .../Source/UIApplicationDelegate+OneSignal.m | 16 ++++++++++++++++ .../InAppMessagingIntegrationTests.m | 2 +- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UIApplicationDelegate+OneSignalNotifications.m b/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UIApplicationDelegate+OneSignalNotifications.m index e5e99f595..50ae12bc7 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UIApplicationDelegate+OneSignalNotifications.m +++ b/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UIApplicationDelegate+OneSignalNotifications.m @@ -34,6 +34,7 @@ #import "OneSignalSelectorHelpers.h" #import "SwizzlingForwarder.h" #import "OSNotificationsManager.h" +#import // This class hooks into the UIApplicationDelegate selectors to receive iOS 9 and older events. // - UNUserNotificationCenter is used for iOS 10 @@ -58,7 +59,7 @@ - (void) setOneSignalDelegate:(id)delegate { Class delegateClass = [delegate class]; - if (delegate == nil || [swizzledClasses containsObject:delegateClass]) { + if (delegate == nil || [OneSignalNotificationsAppDelegate swizzledClassInHeirarchy:delegateClass]) { [self setOneSignalDelegate:delegate]; return; } @@ -93,6 +94,22 @@ - (void) setOneSignalDelegate:(id)delegate { [self setOneSignalDelegate:delegate]; } ++ (BOOL)swizzledClassInHeirarchy:(Class)delegateClass { + if ([swizzledClasses containsObject:delegateClass]) { + [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"OneSignal already swizzled %@", NSStringFromClass(delegateClass)]]; + return true; + } + Class superClass = class_getSuperclass(delegateClass); + while(superClass) { + if ([swizzledClasses containsObject:superClass]) { + [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"OneSignal already swizzled %@ in super class: %@", NSStringFromClass(delegateClass), NSStringFromClass(superClass)]]; + return true; + } + superClass = class_getSuperclass(superClass); + } + return false; +} + - (void)oneSignalDidRegisterForRemoteNotifications:(UIApplication*)app deviceToken:(NSData*)inDeviceToken { [OneSignalNotificationsAppDelegate traceCall:@"oneSignalDidRegisterForRemoteNotifications:deviceToken:"]; diff --git a/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UNUserNotificationCenter+OneSignalNotifications.m b/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UNUserNotificationCenter+OneSignalNotifications.m index b5881f361..61f8ad51e 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UNUserNotificationCenter+OneSignalNotifications.m +++ b/iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UNUserNotificationCenter+OneSignalNotifications.m @@ -33,6 +33,7 @@ #import "UIApplicationDelegate+OneSignalNotifications.h" #import "OSNotificationsManager.h" #import +#import #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" @@ -182,7 +183,7 @@ - (void) setOneSignalUNDelegate:(id)delegate { Class delegateClass = [delegate class]; - if (delegate == nil || [OneSignalUNUserNotificationCenter swizzledClassInHeirarchy:delegateClass]) { + if (delegate == nil || [OneSignalNotificationsUNUserNotificationCenter swizzledClassInHeirarchy:delegateClass]) { [self setOneSignalUNDelegate:delegate]; return; } diff --git a/iOS_SDK/OneSignalSDK/Source/UIApplicationDelegate+OneSignal.m b/iOS_SDK/OneSignalSDK/Source/UIApplicationDelegate+OneSignal.m index d3a63fce0..315c13728 100644 --- a/iOS_SDK/OneSignalSDK/Source/UIApplicationDelegate+OneSignal.m +++ b/iOS_SDK/OneSignalSDK/Source/UIApplicationDelegate+OneSignal.m @@ -80,6 +80,22 @@ - (void) setOneSignalDelegate:(id)delegate { [self setOneSignalDelegate:delegate]; } ++ (BOOL)swizzledClassInHeirarchy:(Class)delegateClass { + if ([swizzledClasses containsObject:delegateClass]) { + [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"OneSignal already swizzled %@", NSStringFromClass(delegateClass)]]; + return true; + } + Class superClass = class_getSuperclass(delegateClass); + while(superClass) { + if ([swizzledClasses containsObject:superClass]) { + [OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"OneSignal already swizzled %@ in super class: %@", NSStringFromClass(delegateClass), NSStringFromClass(superClass)]]; + return true; + } + superClass = class_getSuperclass(superClass); + } + return false; +} + -(void)oneSignalApplicationWillTerminate:(UIApplication *)application { [OneSignalAppDelegate traceCall:@"oneSignalApplicationWillTerminate:"]; diff --git a/iOS_SDK/OneSignalSDK/UnitTests/InAppMessagingIntegrationTests.m b/iOS_SDK/OneSignalSDK/UnitTests/InAppMessagingIntegrationTests.m index 5a4f68312..c05e8b4d8 100644 --- a/iOS_SDK/OneSignalSDK/UnitTests/InAppMessagingIntegrationTests.m +++ b/iOS_SDK/OneSignalSDK/UnitTests/InAppMessagingIntegrationTests.m @@ -26,7 +26,7 @@ of this software and associated documentation files (the "Software"), to deal */ #import -#import "OneSignal.h" +#import "OneSignalFramework.h" #import "OneSignalUserDefaults.h" #import "OneSignalHelper.h" #import "OSInAppMessageInternal.h"