fix(ios): stop hijacking UNUserNotificationCenter.delegate - #3
Open
mr-vishwas wants to merge 1 commit into
Open
Conversation
NotificationManager installed a NotificationDelegate wrapper on UNUserNotificationCenter.delegate to present the library notification while the host app is in the foreground. That property is weak and the wrapper was not retained anywhere, so Kotlin/Native collected it shortly after the first monitored request and the delegate silently became null. From that point the host app received no notification callbacks at all: push notifications stopped being presented in the foreground, and taps no longer reached userNotificationCenter(_:didReceive:withCompletionHandler:), which broke push deep links in a way that is very hard to trace back to a network debugging library. Retaining the wrapper fixes the null delegate but not the underlying problem: the delegate belongs to the host app, and taking it over means competing with whatever the app and its other SDKs install there, in an order the library cannot control. The library no longer touches the delegate, and NotificationDelegate is removed. The notification is still posted and still appears in Notification Center; it is simply no longer presented as a banner while the app is in the foreground, and tapping it no longer routes through the library.
ishaan02-kulu
approved these changes
Aug 20, 2026
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
NotificationManager(iosMain) installed aNotificationDelegatewrapper onUNUserNotificationCenter.delegateso it could present the library notification while the host app is in the foreground:UNUserNotificationCenter.delegateis a weak property, and the wrapper was not retained anywhere. Kotlin/Native collected it shortly after the first monitored request, so the delegate silently becamenull.From that point the host app received no notification callbacks at all:
userNotificationCenter(_:didReceive:withCompletionHandler:), so push deep links stopped working entirely.Because the trigger is the first network call rather than anything notification-related, this is very hard to trace back to a network debugging library. It cost us a full day of investigation in a production app.
Why not just retain the wrapper
Retaining it fixes the
nulldelegate, but the delegate belongs to the host app. Taking it over means competing with whatever the app and its other SDKs (Firebase, MoEngage, …) install there, in an order the library cannot control — and the forwarding chain only works if every participant plays along.Change
The library no longer touches
UNUserNotificationCenter.delegate, andNotificationDelegateis deleted.The notification is still posted and still appears in Notification Center. It is no longer presented as a banner while the app is in the foreground, and tapping it no longer routes through the library. On iOS the monitor UI is opened from the host app anyway (
KtorMonitorViewController), so the delegate bought very little.Version bumped to
1.14.2.Verification
Verified on iOS 26.4 Simulator in an app that uses FCM push with deep links:
UNUserNotificationCenter.current().delegatewas the library'sNotificationDelegateand push taps produced no callback in the app;willPresentanddidReceiveboth fire, and the push payload arrives intact.Android is unaffected by this change but should be sanity-checked before merge, since
NotificationManageris a sharedexpect/actualand only the iOS actual changed.