Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-ios-cold-start-push-open.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'posthog_flutter': patch
---

Fix `$push_notification_opened` not being captured on iOS when the app is cold-launched from a notification tap. Requires posthog-ios 3.72.0, and your app must set `UNUserNotificationCenter.current().delegate` β€” without one iOS reports the tap to nobody.
5 changes: 5 additions & 0 deletions .changeset/push-open-plist-opt-out-scope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'posthog_flutter': patch
---

Change `com.posthog.posthog.CAPTURE_PUSH_NOTIFICATION_OPENED` to also suppress the new iOS cold-start prewarm in apps that do not use `com.posthog.posthog.AUTO_INIT`.
11 changes: 11 additions & 0 deletions example/ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import UIKit
import Flutter
import UserNotifications

@main
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {

// Notification taps only reach the app through a UNUserNotificationCenter delegate; without this
// the SDK has nothing to observe and never captures $push_notification_opened.
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
UNUserNotificationCenter.current().delegate = self
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

private var ownWindow: UIWindow?

func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
Expand Down
4 changes: 2 additions & 2 deletions posthog_flutter/darwin/posthog_flutter.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ Postog flutter plugin
s.ios.dependency 'Flutter'
s.osx.dependency 'FlutterMacOS'

# ~> Version 3.70.0 up to, but not including, 4.0.0
s.dependency 'PostHog', '>= 3.70.0', '< 4.0.0'
# ~> Version 3.72.0 up to, but not including, 4.0.0
s.dependency 'PostHog', '>= 3.72.0', '< 4.0.0'

s.ios.deployment_target = '13.0'
# PH iOS SDK 3.0.0 requires >= 10.15
Expand Down
2 changes: 1 addition & 1 deletion posthog_flutter/darwin/posthog_flutter/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ let package = Package(
],
dependencies: [
.package(name: "FlutterFramework", path: "../FlutterFramework"),
.package(url: "https://github.com/PostHog/posthog-ios", "3.70.0" ..< "4.0.0"),
.package(url: "https://github.com/PostHog/posthog-ios", "3.72.0" ..< "4.0.0"),
],
targets: [
.target(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public class PosthogFlutterPlugin: NSObject, FlutterPlugin {
let instance = PosthogFlutterPlugin()
instance.channel = methodChannel
PosthogFlutterPlugin.instance = instance
prewarmPushNotificationOpenCapture()
initPlugin()
registrar.addMethodCallDelegate(instance, channel: methodChannel)
}
Expand All @@ -94,6 +95,21 @@ public class PosthogFlutterPlugin: NSObject, FlutterPlugin {
private let dispatchQueue = DispatchQueue(label: "com.posthog.PosthogFlutterPlugin",
target: .global(qos: .utility))

/// A cold launch from a notification tap delivers the response about 150ms in, before Dart can
/// reach `Posthog().setup()`. Registration runs inside `didFinishLaunchingWithOptions`, early
/// enough for the native SDK to hold that response until setup() installs the integration.
///
/// The Info.plist key is the only opt-out reachable this early. `setup()` releases an unwanted
/// prewarm afterwards, except when PostHog is already set up with push-open capture disabled and
/// a later `FlutterEngine` registers β€” that setup() has already run, so use the plist key there.
private static func prewarmPushNotificationOpenCapture() {
let capturePushNotificationOpened = Bundle.main.object(forInfoDictionaryKey: "com.posthog.posthog.CAPTURE_PUSH_NOTIFICATION_OPENED") as? Bool ?? true
guard capturePushNotificationOpened else { return }
if #available(iOS 14.0, macOS 11.0, *) {
PostHogSDK.prewarmPushNotificationOpenCapture()
}
}

public static func initPlugin() {
let autoInit = Bundle.main.object(forInfoDictionaryKey: "com.posthog.posthog.AUTO_INIT") as? Bool ?? true
if !autoInit {
Expand Down
3 changes: 3 additions & 0 deletions posthog_flutter/lib/src/posthog_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ class PostHogConfig {
/// warm-start taps on Android.
///
/// **Flutter web:** not supported. Defaults to `true`.
///
/// On iOS this requires your app to set `UNUserNotificationCenter.current().delegate`.
/// Without one, iOS reports the tap to nobody and no open can be captured.
bool capturePushNotificationOpened = true;

/// Mints a signed identity-verification token for push subscription requests.
Expand Down
Loading