iOS ActivityKit: Push Token Issues

1.2k views Asked by At

iOS 16.1 brings ActivityKit that allows to show a Live Activity on Lock Screen (similar to Lock Screen widget but not quite the same).

LiveActivity can receive a limited amount of data per an update (up to 4KB). We send updates to live activity using backend server via APNs. To make backend work we need to get a pushToken from the started LiveActivity and send the token to the backend.

And here're two issues:

Issue #1 - nil token

When an activity is created, pushToken property of that activity is always nil.

        let activity = try Activity.request(
            attributes: attributes,
            contentState: contentState,
            pushType: .token
        )
        print(activity.pushToken) // always nil at this point

So that to get an "initial" token we have to subscribe to pushTokenUpdates and wait for the first available token.

That sounds like a workaround because we expect a started activity should contain a valid token.

Question 1: Is this expected behavior that pushToken is nil right after an activity is started?

Issue #2 - Expired Token

Apple Documentation clearly says that we need to subscribe to push token updates because current token can expire:

Observe changes to an activity’s push token with pushTokenUpdates, send an updated push token to your server, and invalidate the old token on your server.

We subscribed to pushTokenUpdates in the app. But if we close the app or move it to the background, after sometime, the backend receives error 403 from APNS saying that ExpiredProviderToken.

Question 2: What's the life-time of an LiveActivity Push Token? There's no clear documentation that says how often the token refreshes, it sounds like the token can expire while the app in the background. At least this is what we see from our internal tests. Does anyone else experience the same expiration issue with token while the app in the background?

We experience these issues on iOS 16.1 and iOS 16.2. Seems like token always nil when activity is started, and token can expire while the app is in the background.

1

There are 1 answers

0
Quinton Pryce On

The pushToken will always be nil after starting the activity.

You will need to subscribe to the pushTokenUpdates in order to asynchronously receive a token.

let activity = try Activity<ActivityAttributes>.request(
    attributes: attributes,
    contentState: state,
    pushType: .token
)

    
Task {
    for await data in activity.pushTokenUpdates {
        let token = data.map { String(format: "%02x", $0) }.joined()
        print("Event activity \(activity.id) received token \(token)")
    }
}