feat(workflows): add push subscription functionality#545
feat(workflows): add push subscription functionality#545havenbarnes wants to merge 27 commits intomainfrom
Conversation
posthog-ios Compliance ReportDate: 2026-04-28 23:05:58 UTC
|
| Test | Status | Duration |
|---|---|---|
| Request Payload.Request With Person Properties Device Id | ❌ | 224ms |
Failures
request_payload.request_with_person_properties_device_id
404, message='Not Found', url='http://host.docker.internal:8080/get_feature_flag'
ioannisj
left a comment
There was a problem hiding this comment.
A few comments from a first pass
| /// Requires `enableSwizzling` to be `true`. | ||
| /// | ||
| /// Default: true | ||
| @objc public var capturePushNotificationSubscriptions: Bool = true |
There was a problem hiding this comment.
This also silently handles registering push notification token through app delegate swizzling. Should we split these into two different config options?
I also feel we should give users who opt out of this config a manual way to handle this by adding public APIs so they can just forward delegate calls to this SDK (from UNUserNotificationCenterDelegate events and UIApplicationDelegate)
There was a problem hiding this comment.
This also silently handles registering push notification token through app delegate swizzling. Should we split these into two different config options?
You know best here - sounds like there should be an explicit / non-swizzled version? I only opted for this as it felt the most frictionless and I noticed there were other swizzling-required SDK features.
I also feel we should give users who opt out of this config a manual way to handle this by adding public APIs so they can just forward delegate calls to this SDK (from UNUserNotificationCenterDelegate events and UIApplicationDelegate)
Certainly a good idea. I can add this on our side
There was a problem hiding this comment.
You know best here - sounds like there should be an explicit / non-swizzled version? I only opted for this as it felt the most frictionless and I noticed there were other swizzling-required SDK features.
I would have a non-swizzled path as well and maybe even flip the default to false here. App delegate is the entry point for apps, and if something goes wrong with swizzling here (esp with custom classes) we'd be breaking the whole app. @turnipdabeets wdyt?
There was a problem hiding this comment.
Agreed, if we offer this it should be opt-in and maybe 2 separate versions/configs for users who can't swizzle.
There was a problem hiding this comment.
i'd lean to make it as automagically as possible but also give a manual API (opt out by default)
thes less users have to do, the more automatic stuff works the better
swizzle is dangerous, but if done right its super useful
session replay and autocapture only works with swizzle and people use it just fine, except a few folks that prefer to disable everything, we should just respect the config if people disable this config or disable swizzle for everything
There was a problem hiding this comment.
I'm okay with that. Only reason I pushed back a bit here is that this is not using the regular swizzling path which we know works and used by other integrations, but we now handle and need to worry about optional methods from the concrete delegate class (with swizzleAddingIfNeeded())
There was a problem hiding this comment.
yep fair point, so it has to be tested that it does not break, whats the common use cases for swizzling breaking apps?
iOS version? OS (eg ipad vs ios vs macos)? runtime config or something?
figure out and test those use cases
i also think that its quite common to swizzle this code path to make notifications setup automatic, i've seen a few examples on the internet, so i think its common and it should be safe enough, even firebase mentions swizzle a few times which is the main notifications provider for apple if not using APN directly
There was a problem hiding this comment.
We had a similar discussion when deeplinks were implemented on UIKit. I'm okay testing this out as true by default, then we can come back and make deeplinks automagic as well since swizzling app delegate will be there
There was a problem hiding this comment.
Ok, following this thread and (i think) the consensus i've made two changes:
- Set
capturePushNotificationSubscriptions: Bool = falseto default, will make sure this is called out in my documentation PR - Added a non-swizzling codepath for setting up push subscriptions.
LMK if I misinterpreted or anything else is needed here
|
This PR hasn't seen activity in a week! Should it be merged, closed, or further worked on? If you want to keep it open, post a comment or remove the |
ioannisj
left a comment
There was a problem hiding this comment.
We recently refactored PostHogIntegration protocol, so probably that's why CI is failing, should be a quick fix. Todo here I think is exposing manual methods for token registration and have token autodetection with swizzling as an opt-in?
| /// When a push notification is sent from PostHog, the device token is used to deliver the notification to the correct device. | ||
| /// | ||
| /// - Parameter deviceToken: The device token received from the system. | ||
| @objc public func handlePushNotificationDeviceToken(_ deviceToken: Data) { |
There was a problem hiding this comment.
is the deviceToken really a Data? Shouldn't it be a String or something? where do people read this from?
There was a problem hiding this comment.
Depends where it comes from, if they use the swizzled codepath it will be Data. I'll converge this to string to make it more straightforward
There was a problem hiding this comment.
yeah then the swizzling path should do the casting
the public API is gonna be user-friendlier with a String instead
There was a problem hiding this comment.
Not sure I completely agree here since the delegate method is called with Data. So simplest api would be people just forward this call to the sdk?
There was a problem hiding this comment.
https://firebase.google.com/docs/cloud-messaging/ios/get-started#disable-swizzling
i think it depends on what we are collecting here, APN tokens or fcmToken (firebase cloud messaging)?
i understood that Data was only for the swizzling use case, so its automatic, type does not matter
the manual API should have the type that the provider is using, if that is Data, then Data it should be
https://github.com/firebase/firebase-ios-sdk/blob/90c17718b5126b6d95e24c019f10a9fc6a62c54f/FirebaseMessaging/Sources/FIRMessaging.m#L427-L429 here is Data
the firebase link has fcmToken as String
so we just need to figure out what we need and what is its type and that should be the type in the public API
There was a problem hiding this comment.
Ah good point on fcm vs apns tokens. Logic says that we'll need a way to distinguish BE side on this since delivery method will differ? So probably two different public api methods I would say. Swizzling here seems to cover the apns token. For FCM I assume we'll need to stick to manual wiring. Either way, we'd need to know if this is FCM or APNS when delivering the token
There was a problem hiding this comment.
AFAIK, the device tokens format should be the same regardless of delivery platform; FCM ultimately delivers via APNS anyway.
We're not bringing in any FCM-related logic into the SDK - all of the platform differences for delivery happen on the backend here
So I don't think we need to care about anything on the SDK side other than delivering this device token
There was a problem hiding this comment.
the question was more about the datatype really
…d-push-notifications
…d-push-notifications
|
This PR hasn't seen activity in a week! Should it be merged, closed, or further worked on? If you want to keep it open, post a comment or remove the |
|
@ioannisj @turnipdabeets i think this is done, but just need to test/fix conflicts |
💡 Motivation and Context
This will need to be merged after the posthog PR stack PostHog/posthog#53276 and documentation updates:
PostHog/posthog#44444
We're adding push notification channel to workflows, and SDKs need to send us their device tokens to fulfill the push subscription on our end
💚 How did you test it?
Tested everything end to end locally, hitting APNS sandbox on physical device
Added tests for new logic
📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset filereleaselabel to the PR