-
Notifications
You must be signed in to change notification settings - Fork 262
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #926 from OneSignal/fix/pre-existing_notification_…
…delegate_for_master Fix pre-existing notification delegate
- Loading branch information
Showing
9 changed files
with
186 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
iOS_SDK/OneSignalSDK/UnitTests/OneSignalUNUserNotificationCenterSwizzingTest.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#import <objc/runtime.h> | ||
|
||
#import <XCTest/XCTest.h> | ||
|
||
#import "UnitTestCommonMethods.h" | ||
#import "OneSignalExtensionBadgeHandler.h" | ||
#import "UNUserNotificationCenterOverrider.h" | ||
#import "UNUserNotificationCenter+OneSignal.h" | ||
#import "OneSignalHelperOverrider.h" | ||
#import "OneSignalHelper.h" | ||
#import "DummyNotificationCenterDelegate.h" | ||
#import "OneSignalUNUserNotificationCenterHelper.h" | ||
|
||
@interface OneSignalUNUserNotificationCenterSwizzingTest : XCTestCase | ||
@end | ||
|
||
@implementation OneSignalUNUserNotificationCenterSwizzingTest | ||
|
||
// Called BEFORE each test method | ||
- (void)setUp { | ||
[super setUp]; | ||
[UnitTestCommonMethods beforeEachTest:self]; | ||
|
||
[OneSignalUNUserNotificationCenter setUseiOS10_2_workaround:true]; | ||
} | ||
|
||
// Called AFTER each test method | ||
- (void)tearDown { | ||
[super tearDown]; | ||
} | ||
|
||
// Tests to make sure that UNNotificationCenter setDelegate: duplicate calls don't double-swizzle for the same object | ||
- (void)testAUNUserNotificationCenterDelegateAssigningDoesSwizzle { | ||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; | ||
|
||
let dummyDelegate = [[DummyNotificationCenterDelegate alloc] init]; | ||
|
||
IMP original = class_getMethodImplementation([dummyDelegate class], @selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)); | ||
|
||
// This triggers UNUserNotificationCenter+OneSignal.m setOneSignalUNDelegate which does the implemenation swizzling | ||
center.delegate = dummyDelegate; | ||
|
||
IMP swizzled = class_getMethodImplementation([dummyDelegate class], @selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)); | ||
// Since we swizzled the implemenations should be different. | ||
XCTAssertNotEqual(original, swizzled); | ||
|
||
// Calling setDelegate: a second time on the same object should not re-exchange method implementations | ||
// thus the new method implementation should still be the same, swizzled == newSwizzled should be true | ||
center.delegate = dummyDelegate; | ||
|
||
IMP newSwizzled = class_getMethodImplementation([dummyDelegate class], @selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)); | ||
|
||
XCTAssertEqual(swizzled, newSwizzled); | ||
|
||
[OneSignalUNUserNotificationCenterHelper restoreDelegateAsOneSignal]; | ||
} | ||
|
||
- (void)testUNUserNotificationCenterDelegateAssignedBeforeOneSignal { | ||
[OneSignalUNUserNotificationCenterHelper putIntoPreloadedState]; | ||
|
||
// Create and assign a delegate with iOS | ||
let dummyDelegate = [DummyNotificationCenterDelegate new]; | ||
UNUserNotificationCenter.currentNotificationCenter.delegate = dummyDelegate; | ||
|
||
// Save original implemenation reference, before OneSignal is loaded. | ||
IMP originalDummyImp = class_getMethodImplementation([dummyDelegate class], @selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)); | ||
|
||
// Setup the OneSignal delegate where it will be loaded into memeory | ||
[OneSignalUNUserNotificationCenter setup]; | ||
|
||
IMP swizzledDummyImp = class_getMethodImplementation([dummyDelegate class], @selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)); | ||
|
||
// Since we swizzled the implemenations should be different. | ||
XCTAssertNotEqual(originalDummyImp, swizzledDummyImp); | ||
|
||
[OneSignalUNUserNotificationCenterHelper restoreDelegateAsOneSignal]; | ||
} | ||
|
||
@end |
10 changes: 10 additions & 0 deletions
10
...SDK/OneSignalSDK/UnitTests/UNNotificationCenter/OneSignalUNUserNotificationCenterHelper.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#import <Foundation/Foundation.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface OneSignalUNUserNotificationCenterHelper : NSObject | ||
+ (void)restoreDelegateAsOneSignal; | ||
+ (void)putIntoPreloadedState; | ||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
37 changes: 37 additions & 0 deletions
37
...SDK/OneSignalSDK/UnitTests/UNNotificationCenter/OneSignalUNUserNotificationCenterHelper.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#import "OneSignalUNUserNotificationCenterHelper.h" | ||
|
||
#import "UNUserNotificationCenter+OneSignal.h" | ||
#import "OneSignalHelper.h" | ||
|
||
@implementation OneSignalUNUserNotificationCenterHelper | ||
|
||
// Call this after you assign UNUserNotificationCenter.currentNotificationCenter.delegate to restore | ||
// the delegate as well as swizzling effects. | ||
// In a nutshell this swizzles a 2nd time in reverse to swap method implementations back. | ||
+ (void)restoreDelegateAsOneSignal { | ||
// Undo swizzling of notification events by swizzling again to swap method implementations back. | ||
[OneSignalUNUserNotificationCenter swizzleSelectorsOnDelegate:UNUserNotificationCenter.currentNotificationCenter.delegate]; | ||
|
||
// Temp unswizzle setDelegate, so we can re-assign the delegate below without side-effects. | ||
[OneSignalUNUserNotificationCenter swizzleSelectors]; | ||
|
||
// Clear the delegate and call registerAsUNNotificationCenterDelegate so it assigns OneSignal | ||
// as the delegate like it does the first time when it is loaded into memory. | ||
UNUserNotificationCenter.currentNotificationCenter.delegate = nil; | ||
[OneSignalUNUserNotificationCenter registerDelegate]; | ||
|
||
// Undo our temp unswizzle by swizzle one more time. Undo our undo :) | ||
[OneSignalUNUserNotificationCenter swizzleSelectors]; | ||
} | ||
|
||
// OneSignal auto swizzles UNUserNotificationCenterDelegate when the class is loaded into memory. | ||
// This undoes this affect so we can test setup a pre-loaded OneSignal state. | ||
// Why? This way we can setup a senario where someone else's delegate is assigned before OneSignal get loaded. | ||
+ (void)putIntoPreloadedState { | ||
// Swizzle to undo the swizzle. (yes, swizzling a 2nd time reverses the swizzling) | ||
[OneSignalUNUserNotificationCenter swizzleSelectors]; | ||
|
||
// Unassign OneSignal as the delegate | ||
UNUserNotificationCenter.currentNotificationCenter.delegate = nil; | ||
} | ||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters