77#import " TestHelperFunctions.h"
88#import " OneSignalAppDelegateOverrider.h"
99
10+ #define ONESIGNALApplicationDelegate UIApplicationDelegate
11+
1012@interface AppDelegateForAddsMissingSelectorsTest : UIResponder <UIApplicationDelegate>
1113@end
1214@implementation AppDelegateForAddsMissingSelectorsTest
@@ -90,7 +92,8 @@ @interface AppDelegateForInfiniteLoopWithAnotherSwizzlerTest : UIResponder<UIApp
9092@end
9193@implementation AppDelegateForInfiniteLoopWithAnotherSwizzlerTest
9294@end
93- @interface OtherLibraryASwizzler : NSObject
95+
96+ @interface OtherLibraryASwizzler : UIResponder <ONESIGNALApplicationDelegate>
9497+(void )swizzleAppDelegate ;
9598+(BOOL )selectorCalled ;
9699@end
@@ -109,6 +112,7 @@ +(void)swizzleAppDelegate
109112 @selector (applicationWillTerminateLibraryA: )
110113 );
111114}
115+
112116- (void )applicationWillTerminateLibraryA : (UIApplication *)application
113117{
114118 selectorCalled = true ;
@@ -118,6 +122,33 @@ - (void)applicationWillTerminateLibraryA:(UIApplication *)application
118122}
119123@end
120124
125+
126+ @interface OtherLibraryBSwizzlerSubClass : OtherLibraryASwizzler
127+ @end
128+ @implementation OtherLibraryBSwizzlerSubClass
129+ +(BOOL )selectorCalled {
130+ return selectorCalled;
131+ }
132+
133+ +(void )swizzleAppDelegate
134+ {
135+ swizzleExistingSelector (
136+ [UIApplication.sharedApplication.delegate class ],
137+ @selector (applicationWillTerminate: ),
138+ [self class ],
139+ @selector (applicationWillTerminateLibraryB: )
140+ );
141+ }
142+
143+ - (void )applicationWillTerminateLibraryB : (UIApplication *)application
144+ {
145+ selectorCalled = true ;
146+ // Standard basic swizzling forwarder another library may have.
147+ if ([self respondsToSelector: @selector (applicationWillTerminateLibraryB: )])
148+ [self applicationWillTerminateLibraryB: application];
149+ }
150+ @end
151+
121152@interface AppDelegateForExistingSelectorsTest : UIResponder <UIApplicationDelegate> {
122153 @public NSMutableDictionary *selectorCallsDict;
123154}
@@ -408,6 +439,36 @@ - (void)testDoubleSwizzleInfiniteLoop {
408439 [localOrignalDelegate applicationWillTerminate: UIApplication.sharedApplication];
409440}
410441
442+ - (void )testAppDelegateSubClassIsNotSwizzledTwice {
443+ // 1. Create a new delegate and assign it
444+ id myAppDelegate = [AppDelegateForInfiniteLoopWithAnotherSwizzlerTest new ];
445+ UIApplication.sharedApplication .delegate = myAppDelegate;
446+
447+ // 2. Create another Library's app delegate and assign it then swizzle
448+ id thierAppDelegate = [OtherLibraryASwizzler new ];
449+ UIApplication.sharedApplication .delegate = thierAppDelegate;
450+ [OtherLibraryASwizzler swizzleAppDelegate ];
451+
452+ // 3. Create another Library's app delegate subclass and assign it then swizzle
453+ id thierAppDelegateSubClass = [OtherLibraryBSwizzlerSubClass new ];
454+ UIApplication.sharedApplication .delegate = thierAppDelegateSubClass;
455+ [OtherLibraryBSwizzlerSubClass swizzleAppDelegate ];
456+
457+ // 4. Call something to confirm we don't get stuck in an infinite call loop
458+ id <UIApplicationDelegate> delegate = UIApplication.sharedApplication .delegate ;
459+ [delegate applicationWillTerminate: UIApplication.sharedApplication];
460+
461+ // 5. Ensure OneSignal's selector is called.
462+ XCTAssertEqual ([OneSignalAppDelegateOverrider
463+ callCountForSelector: @" oneSignalApplicationWillTerminate:" ], 1 );
464+
465+ // 6. Ensure other library selector is still called too.
466+ XCTAssertTrue ([OtherLibraryASwizzler selectorCalled ]);
467+
468+ // 7. Ensure other library subclass selector is still called too.
469+ XCTAssertTrue ([OtherLibraryASwizzler selectorCalled ]);
470+ }
471+
411472- (void )testCompatibleWithOtherSwizzlerWhenSwapingBetweenNil {
412473 // 1. Create a new delegate and assign it
413474 id myAppDelegate = [AppDelegateForInfiniteLoopWithAnotherSwizzlerTest new ];
@@ -624,4 +685,5 @@ - (void)testAppDelegateInheritsFromBaseWhereBothHaveSelectorsButSuperIsNotCalled
624685 XCTAssertFalse (myAppDelegate.selectorCalledOnParent );
625686 XCTAssertEqual ([OneSignalAppDelegateOverrider callCountForSelector: @" oneSignalReceiveRemoteNotification:UserInfo:fetchCompletionHandler:" ], 1 );
626687}
688+
627689@end
0 commit comments