fix(push): capture $push_notification_opened on iOS cold start - #556
Draft
turnipdabeets wants to merge 3 commits into
Draft
fix(push): capture $push_notification_opened on iOS cold start#556turnipdabeets wants to merge 3 commits into
turnipdabeets wants to merge 3 commits into
Conversation
Plugin registration runs inside didFinishLaunchingWithOptions, early enough to prewarm the native push-open swizzles before the tap response is delivered — Dart-side setup() lands about 90ms too late. Also wires UNUserNotificationCenter.current().delegate into the example app; without a delegate iOS reports the tap to nobody and no open is capturable at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012txiHBCZRkShMdE7V25Jrd
5 tasks
Contributor
posthog-flutter Compliance ReportDate: 2026-09-02 15:50:53 UTC ✅ All Tests Passed!45/45 tests passed Capture Tests✅ 29/29 tests passed View Details
Feature_Flags Tests✅ 16/16 tests passed View Details
|
…quisite The podspec and Package.swift still allowed 3.70.0/3.71.0, neither of which has prewarmPushNotificationOpenCapture(), so a consumer with a locked Podfile.lock would have hit a compile error rather than the fix. Also names the UNUserNotificationCenter delegate requirement, which is the other half of the reported bug and was previously only fixed in the example. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012txiHBCZRkShMdE7V25Jrd
5 tasks
It still named 3.70.0 directly above the raised 3.72.0 requirement. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012txiHBCZRkShMdE7V25Jrd
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.
💡 Motivation and Context
Fixes #555 —
$push_notification_openedis never captured on iOS. Reproduced on a simulator; two independent causes:UNUserNotificationCenterdelegate, so iOS reports the tap to nobody and the native SDK's swizzling has nothing to attach to. (Noteflutter_local_notificationsdoes not set it either — it registers as an application delegate and relies onFlutterAppDelegateforwarding.)didReceivearrives ~150 ms in, about 90 ms before Dart reachesPosthog().setup().PostHogSDK.prewarmPushNotificationOpenCapture(). The podspec andPackage.swiftfloors are already raised to>= 3.72.0, so merging or releasing this before posthog-ios 3.72.0 is published failspod install/ SPM resolution for every iOS user — a hard build break, not a degradation. Draft until then.💚 How did you test it?
On device — posthog-flutter example app, iPhone 17 Pro sim / iOS 26.4, built against a local posthog-ios with the native change:
flutter analyzeclean. The native unit tests live in the posthog-ios PR.Testing
Verified on an iPhone 17 Pro simulator (iOS 26.4) against a local
posthog-iosbuild, with events confirmed in a real PostHog project:capturePushNotificationOpened: falseAppDelegatewith the delegate line removedRepeated across four rounds — 15
$push_notification_openedevents ingested in total, carrying$notification_titleand$notification_body.📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Built with Claude Code (session), driven by @turnipdabeets. Nearly all the logic lives in posthog-ios; this side is the trigger plus the example wiring.
Worth a reviewer's attention:
prewarmPushNotificationOpenCapture()is called fromregister(with:)because that runs insidedidFinishLaunchingWithOptions.AUTO_INITwould also win the race (verified), but it is mutually exclusive withpushIdentityProvider, so it isn't a usable answer for everyone.capturePushNotificationOpened: falseisn't known yet. The native SDK releases an unwanted prewarm atsetup(), so this only matters for one add-to-app ordering, documented at the call site. That widens the key's scope beyondAUTO_INITapps, hence the second changeset.AppDelegatechange is the fix for cause (1) and is the copy-pasteable bit for users hitting this.Not done here, deliberately: a README/docs section (the SDK currently ships push with no iOS setup docs at all). The identical cold-start race exists in
@posthog/react-native-pluginand needs a follow-up issue on posthog-js.