Issue starting Live Activities with ActivityKit push notifications

Hi all,

I'm trying to implement starting Live Activities with push notifications according to this article:

https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications

I'm using Xcode 15.1 beta 3, I have run my tests on a physical device with iOS 17.2 as well as the simulator with iOS 17.2

My problem is I can't seem to be able to get the pushToStartToken needed to start the live activities. I have subscribed to the pushToStartTokenUpdates but I never get any updates.

Here is the code I used:

        Task {
            do {
                for try await data in Activity<DailyGoalActivityAttributes>.pushToStartTokenUpdates {
                    let token = data.map {String(format: "%02x", $0)}.joined()
                    print("Activity token: \(token)")
                }
            } catch {
                print(error)
            }

        }

Any help would be greatly appreciated.

Thanks,

HS

Post not yet marked as solved Up vote post of hs-dev Down vote post of hs-dev
1.9k views
  • My observations have been: the new api (from iOS 17.2) Activity<ActivityAttributes>.pushToStartTokenUpdates returns the pushToStartToken is when Activity<ActivityAttributes>.request has been made (when app is in foreground).

    This blog talks about the sequence but it doesn't seem to be working as designed. https://apnspush.com/how-to-start-and-update-live-activities-with-push-notifications

Add a Comment

Replies

After downloading Xcode 15.1 RC I can get it to work on my device (updated with the latest beta), still not working in the simulator.

  • I am getting 410 Unregistered when sending to the start token.

    Do you have an example payload you sent?

  • I got it working to start a live activity via push notification. Now, how do I get the id of the activity I just started via a push notification? Has anyone been able to do this? Thanks!

  • How did you start the live push activity?

Add a Comment

The only way I found to get the token to update a live activity created through a push notification was to put the following code in my AppDelegate application didFinishLaunchingWithOptions method. I'm able to update a live activity created using push notifications using the token from pushTokenUpdates.

But there is a major design flow IMO, since you can start a live activity without your app being running the following code will never get hit in that instance, and without a way to retrieve the update token from the server side there will be no way of updating the live activity...

I must be missing something but the doc is not helpful in its current state.

Task {
            //
            // Wait for newly created live activities
            //
            for await activityData in Activity<DailyGoalActivityAttributes>.activityUpdates {
                Task {
                    //
                    // Wait for the token needed to update a live activity using push notifications.
                    //
                    for await tokenData in activityData.pushTokenUpdates {
                        let token = tokenData.map {String(format: "%02x", $0)}.joined()
                        print("Push token: \(token)")
                    }
                }
            }
        }
  • Yes, that has been my observation too.

    make a call to Activity<ActivityAttributes>.request (when app is in foreground)Activity<ActivityAttributes>.pushToStartTokenUpdates returns the pushToStartToken

    This defeats the purpose of the new api. The scenario that companies are interested in is mentioned in a blog https://onesignal.com/blog/new-activitykit-notifications-push-the-boundaries-of-current-ios-live-activities/

  • Were you guys able to solve the issue? I'm currently experiencing exactly the same, tried reacting to didReceiveRemoteNotification and access Activity<MyAttributes>.activities.last and then initialize the task that observes the pushToken for that specific activity but it doesn't work.

Add a Comment

Regarding the payload, here is a working example:

curl -v \
  --header "authorization: bearer ${AUTHENTICATION_TOKEN}" \
  --header "apns-topic: com.yourcompany.app.ios.push-type.liveactivity" \
  --header "apns-push-type: liveactivity" \
  --header "apns-priority: 10" \
  --header "apns-expiration: 0" \
  --data '{"aps":{"timestamp":'$(date +%s)', "event":"start", "content-state": {"currentValue":40000,"targetValue":50000}, "attributes-type":"MyActivityAttributes","attributes":{"currentValue":40000,"targetValue":50000},"alert":{"title":"Almost there!","body":"You have reached 75% of your goal!"}}}' \
  --http2  https://api.development.push.apple.com:443/3/device/${PUSH_TO_START_TOKEN}

From my experience, it seems that pushToStartTokenUpdates, and similarly pushToStartToken, will only trigger on a fresh app install + having rebooted your device + calling this method in didFinishLaunchingWithOptions, and it has to be that specific combination all at once. That means:

  1. Uninstalling and reinstalling the app will not trigger this token again.
  2. Simply restarting your device without reinstalling the app will also not trigger this token.
  3. If you call this stream in didFinishLaunchingWithOptions, you'll never get the token again unless steps 1 & 2 are also taken first.

This doesn't seem like ideal behavior, as there may be a situation where my application may not be ready to process that push-to-start token. Basically, if my user misses that window to retrieve and process the token, they'll basically never be able to receive a Live Activity. I imagine this is a bug and hopefully gets resolved sooner rather than later.

I realise I’m piling on here, but this thread seems to be the only place on the Internet where this functionality is being discussed.

Where there are static attributes of your ActivityAttributes class, how are you reflecting those in the push to start payload? The example provided by Apple is a little confusing as it has the same model for content-state and attributes.

Post not yet marked as solved Up vote reply of bkd Down vote reply of bkd
  • I figured it out. Will write it up if I have time.

Add a Comment

Could anybody provide insight on how exactly the Live Activity is created via the push notification. Apple's docs state "When the system receives the ActivityKit push notification on a device, it starts a new Live Activity, wakes up your app, and grants it background run time to allow you to download assets that the Live Activity needs." Can anybody elaborate on how/where exactly this happens?

I'm able to successfully obtain the pushToStartToken and can successfully deliver APNS payload via CloudKit - Push Notifications tool. I see in the delivery logs that my push notification was both received by the APNS server and successfully delivered to target device. Once delivered, I see my pushToStartTokenUpdates trigger once more and can get an updated token but, I don't fully understand how/where the live activity is actually created. Any information would be much appreciated

  • Update - My APNS payload WAS being delivered successfully however, there were discrepancies resulting in decoding error. Once those were resolved, I now see the live activity being created

  • @tjait05 Have you been able to get your token for updates when the push for starting a Live Activity is delivered when the app is in background? Where/how do you get it? I also struggle to find where this is happening: "When the system receives the ActivityKit push notification on a device it [...] wakes up your app, and grants it background run time". I see that Live Activity is started, but that's all, unless the app was already running.

  • @lena.l I have not been able to obtain the push token for updates reliably. I have tried the snippet above which technically works although as @hs-dev mentions, this has many design flaws. I'm still searching for answers myself.

Add a Comment

I was experiencing this same issue. To resolve, I added this to my info.plist file. Supports Live Activities: YES

After doing this, I immediately started receiving the token on the next call.