[Fix] swizzling not forwarding with apps that use UIApplicationDelegateAdaptor #1091
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
One Line Summary
Fix some
AppDelegate
methods not being called when the app uses@UIApplicationDelegateAdaptor
. Includes a secondary fix for rare stack overflow bug due to duplicate implementations with swizzling theUNUserNotificationCenterDelegate
.Details
Motivation
OneSignal should not cause side effects to AppDelegate events. The following are not firing when
@UIApplicationDelegateAdaptor
is used:application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
application(_:didFailToRegisterForRemoteNotificationsWithError:)
application(_:didRegisterForRemoteNotificationsWithDeviceToken:)
applicationWillTerminate(_:)
The motivation to fix the stack overflow bug due to double swizzling in this PR is that it was required to address to write tests. It's possible to run into in an app setup too, however it's questionable if such a situation would happen.
Scope
Effects swizzling logic, includes double swizzling detection to prevent infinite loops for both
AppDelegate
andUNUserNotificationCenterDelegate
. Also calling original implementation ofAppDelegate
selectors noted above in the Motivation section.Related Issues
fixes #1045
Apple's @UIApplicationDelegateAdaptor and SwiftUI.AppDelegate
The inter workings of
@UIApplicationDelegateAdaptor
is unknown it was discovered that theAppDelegate
set is an privateSwiftUI.AppDelegate
class. This class doesn't include selectors for the events noted above in the Motivation section. When these selectors are added to this class via our swizzling code the methods on the app's@UIApplicationDelegateAdaptor
instance are no longer called. We discovered however that callingforwardingTargetForSelector:
onSwiftUI.AppDelegate
returns the instance of@UIApplicationDelegateAdaptor
set by the app. We ended up using this as a fallback ifrespondsToSelector:
is false.Follow up PR, use SwizzlingForwarder consistency
This PR added a new
SwizzlingForwarder
class to make sure we forward the event to prevent side effects. However this PR did not add this toUNUserNotificationCenterDelegate
to keep this scope down.Testing
Unit testing
Manual testing
Tested on Xcode 13.3.1 on an iOS simulator and an iPhone 6s with iOS 14.4.1.
Tested with Objective-C and Swift with SwiftUI.
Tested to ensure
didFailToRegisterForRemoteNotificationsWithError:
anddidRegisterForRemoteNotificationsWithDeviceToken:
fire in the app's AppDelegate.Affected code checklist
Checklist
Overview
Testing
Final pass
This change is