Skip to content

docs(push): add iOS Live Activities page#3464

Open
ttypic wants to merge 1 commit into
mainfrom
liveactivity-section
Open

docs(push): add iOS Live Activities page#3464
ttypic wants to merge 1 commit into
mainfrom
liveactivity-section

Conversation

@ttypic

@ttypic ttypic commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Description

Document starting, updating, and ending iOS Live Activities via Ably-managed APNs broadcast channels: device registration with push-to-start tokens, broadcast channel creation, the start/update/end server calls, and an aps payload and headers reference. Marked Experimental.

Checklist

Document starting, updating, and ending iOS Live Activities via
Ably-managed APNs broadcast channels: device registration with
push-to-start tokens, broadcast channel creation, the start/update/end
server calls, and an aps payload and headers reference. Marked
Experimental.
@ttypic ttypic requested a review from m-hulbert July 8, 2026 12:55
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4d926b4f-024c-4b3a-9ed5-052da98d91c2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch liveactivity-section

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.


* An Ably app with [APNs configured](/docs/push/configure/device#apns): upload your APNs signing key so Ably can push on your behalf.
* An iOS app with the `NSSupportsLiveActivities` Info.plist key, a Live Activity widget extension, and an `ActivityAttributes` model.
* iOS 16.1 or later for Live Activities; iOS 17.2 or later for push-to-start and broadcast channels.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS 16.1 or later for Live Activities

What functionality does Ably give you if you're on iOS < 17.2? It seems like all our functionality is built around broadcast channels.


## Prerequisites <a id="prerequisites"/>

* An Ably app with [APNs configured](/docs/push/configure/device#apns): upload your APNs signing key so Ably can push on your behalf.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That page seems to default to Java, which doesn't have #apns; I think /docs/push/configure/device?lang=swift#apns

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I need to verify this in the review app; I just navigated directly to the page

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, just tried it in the review app; this link doesn't work


<Code>
```swift
rest.push.activate(pushToStart: token)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where can I find this API? It's not in ably/ably-cocoa#2219


Live Activities display an app's live state on the iOS lock screen and in the Dynamic Island, for example a sports scoreboard, a delivery tracker, or the progress of a long-running task. Apple updates Live Activities through APNs rather than through the app itself, which normally means collecting and refreshing a push token for every activity on every device.

Ably removes that bookkeeping. Ably holds your APNs credentials, manages [APNs broadcast channels](https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications) on your behalf, and fans a single publish out to every activity subscribed to the broadcast channel. Your server starts, updates, and ends Live Activities with three API calls, and devices register themselves using the same [push activation](/docs/push/configure/device) flow used for ordinary push notifications.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and fans a single publish out to every activity subscribed to the broadcast channel

Isn't it APNs that "fans out"? That's what we say further down:

APNs fans it out to every subscribed activity on every device — no per-activity tokens involved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I think I didn't have the right mental model here, will come back to this comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So as I understand it, what Ably fans out is the creation of the activity (to each matching device), not the updates (which is handled by APNs) — "and fans a single publish out to every activity subscribed to the broadcast channel" suggests we handle the latter

@lawrence-forooghian

Copy link
Copy Markdown
Contributor

Probably a question for the devex team but is there a way to force it to show something for a snippet even if it's not in the selected language? Else you have to keep flipping the language selector between JS and Swift to view the full page.

```
</Code>

Finally, make the device targetable for push-to-start. Either subscribe it to an Ably channel:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a while to understand why Ably channels are introduced here. I think it would be useful to say something like "the Ably channel is only used to select which devices to push-to-start; it has nothing to do with the broadcast channel that carries updates"


Live Activities display an app's live state on the iOS lock screen and in the Dynamic Island, for example a sports scoreboard, a delivery tracker, or the progress of a long-running task. Apple updates Live Activities through APNs rather than through the app itself, which normally means collecting and refreshing a push token for every activity on every device.

Ably removes that bookkeeping. Ably holds your APNs credentials, manages [APNs broadcast channels](https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications) on your behalf, and fans a single publish out to every activity subscribed to the broadcast channel. Your server starts, updates, and ends Live Activities with three API calls, and devices register themselves using the same [push activation](/docs/push/configure/device) flow used for ordinary push notifications.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

three API calls

Feels a bit misleading since it's actually a one-time create plus the three lifecycle calls

Comment on lines +19 to +25
1. **Create a broadcast channel.** Your server asks Ably to create an APNs broadcast channel. Ably returns a pair of identifiers: an opaque broadcast `id`, which your server uses in every subsequent start, update, and end call, and an `apnsChannelId`, which iOS devices use to subscribe an activity to the channel.

2. **Start the Live Activity.** Either:
* **Push-to-start from the server.** Devices that have registered a Live Activity push-to-start token with Ably can have activities started remotely. The start payload includes the `apnsChannelId` (as `input-push-channel`), so the started activity is subscribed to the broadcast channel immediately.
* **Locally in the app.** The app starts the activity itself with `pushType: .channel(apnsChannelId)`, subscribing it to the broadcast channel.

3. **Update and end by broadcast.** Each state change is a single publish against the broadcast `id`. APNs fans it out to every subscribed activity on every device — no per-activity tokens involved. Creating the channel with `messageStoragePolicy: 1` caches the most recent update so late-joining activities receive the current state as soon as they subscribe.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think the style guide prohibits bold list prefixes as well as em-dashes

* An Ably app with [APNs configured](/docs/push/configure/device#apns): upload your APNs signing key so Ably can push on your behalf.
* An iOS app with the `NSSupportsLiveActivities` Info.plist key, a Live Activity widget extension, and an `ActivityAttributes` model.
* iOS 16.1 or later for Live Activities; iOS 17.2 or later for push-to-start and broadcast channels.
* Clients should authenticate with [token authentication](/docs/auth/token) — for example an `authUrl` pointing at your server — so the API key never ships in the app.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style guide (em-dashes)

```
</Code>

If the device only needs Live Activity push-to-start — and never ordinary push notifications — activate with the push-to-start token alone. This registers the device without requesting an APNs device token:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style guide (em-dashes)


## Prerequisites <a id="prerequisites"/>

* An Ably app with [APNs configured](/docs/push/configure/device#apns): upload your APNs signing key so Ably can push on your behalf.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use ".p8 authentication key" rather than "signing key"? Check with Claude and it seems to be the term the linked page and all other push docs use

* `Date` properties in attributes or content state travel as Unix epoch **seconds**, which is how ActivityKit decodes JSON dates by default.
</Aside>

## Prerequisites <a id="prerequisites"/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also add a point saying the key/token needs the push-admin capability?


* An Ably app with [APNs configured](/docs/push/configure/device#apns): upload your APNs signing key so Ably can push on your behalf.
* An iOS app with the `NSSupportsLiveActivities` Info.plist key, a Live Activity widget extension, and an `ActivityAttributes` model.
* iOS 16.1 or later for Live Activities; iOS 17.2 or later for push-to-start and broadcast channels.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't broadcast channels only available from iOS 18+? And 17.2 is push-to-start only?

```
</Code>

The underlying REST endpoint is `POST /push/apnsBroadcastChannels/{id}/broadcast`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add one clause on why update() posts to /broadcast — an update is a single broadcast to the channel

| `attributes-type` | start | The exact name of the Swift `ActivityAttributes` struct. |
| `attributes` | start | The activity's fixed attributes; `Date` values as Unix epoch seconds. |
| `input-push-channel` | start | The `apnsChannelId` the started activity subscribes to for broadcast updates. |
| `alert` | start | The user-visible notification shown when the activity starts. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this also used in update (not just start)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-app Create a Heroku review app

Development

Successfully merging this pull request may close these issues.

4 participants