Agent Wranglers

NTF-42Recommended

Keep Live Activity push tokens apart from device tokens

Store each Live Activity's push token and push-to-start token apart from the device token, and replace them when the app reports new ones. Send updates with the liveactivity push type.

How to do it

An iOS Live Activity, such as a delivery tracker on the Lock Screen, gets its own push token. Apple says to read it from the pushTokenUpdates sequence, because it can change, and to send each new value to your server. A push-to-start token, from pushToStartTokenUpdates, lets the server start an activity while the app is closed. Send to APNs with the apns-push-type header set to liveactivity and the topic <bundle ID>.push-type.liveactivity. Set event to start, update or end, and timestamp to the current time, so the phone shows the newest state. Delete the token when the activity ends, as Delete dead subscriptions and tokens at once says. The device token keeps carrying ordinary pushes, as Use the current APNs and FCM interfaces says.

Examples

Plain text example

Task {
    for await token in activity.pushTokenUpdates {
        let hex = token.map { String(format: "%02x", $0) }.joined()
        try await api.saveActivityToken(activityId: activity.id, token: hex)
    }
}

JavaScript example

export async function updateLiveActivity(activity, contentState) {
  await apns.send({
    token: activity.pushToken,
    headers: { 'apns-push-type': 'liveactivity', 'apns-topic': `${BUNDLE_ID}.push-type.liveactivity`, 'apns-priority': '10' },
    payload: { aps: { timestamp: Math.floor(Date.now() / 1000), event: 'update', 'content-state': contentState } },
  });
}

Python example

import time

def update_live_activity(activity, content_state: dict) -> None:
    apns.send(
        token=activity.push_token,
        headers={"apns-push-type": "liveactivity", "apns-topic": f"{BUNDLE_ID}.push-type.liveactivity", "apns-priority": "10"},
        payload={"aps": {"timestamp": int(time.time()), "event": "update", "content-state": content_state}},
    )

How to check

A server test sends an update for an activity. The APNs request carries apns-push-type: liveactivity, the .push-type.liveactivity topic and the activity's own token, never the device token. A test that reports a new activity token replaces the stored one.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/notifications/native-push/live-activity-tokens">Agent Wranglers notifications playbook</a>. In code you write, add a comment next to it with the same link.