Start and Update iOS Live Activities With Broadcast Push Notifications
The forth part of a series on Live Activities.
- What are iOS Live Activities and Four Kinds of Presentations
- Add Live Activities to Your iOS App in 5 Steps
- Start and Update iOS Live Activities With Push Notifications
- Start and Update iOS Live Activities With Broadcast Push Notifications
Starting with iOS 18 and iPadOS 18, users can subcribe on a channel, then you can send a single broadcast push notification to update all their live activities, rather than sending multiple push notifications using each individual's device token.
Step0: Main flow
The figure below describes the main flow:
- Your server communicates with Apple Push Notification service(APNs) to create a channel and get a channel ID.
Then, there are two approaches to create a Live Activity that subscribes for broadcast push notification.
- Your server sends this channel ID to your app, and then your app use this channel ID to create a Live Activity by code that subscribes for broadcast push notifications on this channel.
- Your server sends a push-to-start notification with the channle ID, and then the system will create a Live Activity for you that subscribes for broadcast push notifications on this channel.
Step1: Enable broad capability in your AppID
Signing on to developer.apple.com.
- Go to Certificates, IDs & Profiles > Identifiers
- Select the AppID you want to enable Broadcast Capability
- Enable Broadcast Capability under Push Notifications and save.
Step2: Create a channel
You can maintain up to 10,000 channels for your app in the development and production environment, respectively.
You can use one of the following ways to create a channel:
- Use Apple's Apple Push Notification Console.
- Manually request channel management request API following Apple's instruction.
- Use my own APNs Channels tools which will request channel management request API.
WARNING
When I request Apple's channel management API with a bundleID that contains capital letters, I always receive a "TopicMismatch" error. I'm unsure why this is happening, as Apple's own Push Notification Console doesn't have this issue.
You can find the details of my request here.
Here are the steps to create a channel using my APNs Channels tool.
- Select "Authenticate using tokens" and provide the P8 key file, Key ID, Team ID.
- Select the "Environment" and enter the
Bundle ID
, excluding the ".push-type.liveactivity" suffix. - Click the "+ New Channel" button.
- In the popup window, select the "Message Storage Policy".
- Then, click the "Create Channel" button.
- Then, go back to the main page, you will find the new created channel information in the list below.
The ChannelID column is all you need.
Step3: Start a channel-subscribed Live Activity by code
In your app, you can manually start a Live Activity by calling the request(attributes:content:pushType:)
function and pass channel with the channel ID
as the pushType
parameter.
func startLiveActivityWithChannel(string channelId, initialState) {
let activity = try Activity.request(
attributes: adventure,
content: .init(state: initialState, staleDate: nil),
//Input your unique channel ID
pushType: .channel(channelId)
}
Step4: Start a channel-subscribed Live Activity using push notifications
You can also start a channel-subscribed Live Activity by adding input-push-channel
field to the payload of regular push-to-start Live Activity push notificaitons.
Host
Use HTTP/2 and TLS 1.2 or later to establish a connection between your provider server and one of the following servers.
- Development/Sandbox Environment:
api.sandbox.push.apple.com:443
- Production Environment:
api.push.apple.com:443
Request Header
- :method:
POST
- :path:
/3/device/<push_to_start_token>
- authorization:
bearer <provider_token>
- apns-push-type:
liveactivity
- apns-topic:
<your bundleID>.push-type.liveactivity
- apns-priority:
5
or10
Payload
- timestamp: Current UNIX timestamp in seconds.
- event:
start
- input-push-channel:
<Channel ID>
. - attributes-type: Your custom ActivityAttributes type.
LiveActivityAttributes
in my case. - attributes: Static data of your live activity content.
- content-state: Dynamic data of your live activity content.
- alert: Alert the user about a new Live Activity.
{
"aps": {
"timestamp": 1705547770,
"event": "start",
"input-push-channel": "CTrNsYq/Ee8AALLzHQaVlA==",
"content-state": {
"emoji": "🍏🍏"
},
"attributes-type": "LiveActivityAttributes",
"attributes": {
"name": "Apple"
},
"alert": {
"title": "Hello",
"body": "World",
"sound": "chime.aiff"
}
}
}
Step4: Update a channel-subscribed Live Activity With Broadcast Push Notifications
Then, you can update the Live Activity by sending update
push notifications to the channel ID.
Host
Use HTTP/2 and TLS 1.2 or later to establish a connection between your provider server and one of the following servers.
- Development/Sandbox Environment:
api.sandbox.push.apple.com:443
- Production Environment:
api.push.apple.com:443
Request Header
- :method:
POST
- :path:
/4/broadcasts/apps/<your bundleID>
(bundle ID excluding the .push-type.liveactivity suffix) - authorization:
bearer <provider_token>
- apns-push-type:
liveactivity
- apns-priority:
5
or10
- apns-channel-id:
<Channel ID>
- apns-expiration: UNIX timestamp in seconds represents the notification expiration time. If the channel's storage policy is
No Message Stored
, this value must not be zero.
Payload
- timestamp: Current UNIX timestamp in seconds.
- event:
update
- content-state: The latest dynamic data of your live activity content.
- stale-date(optional): UNIX timestamp in seconds represents the time when the system will consider the Live Activity to be stale.
{
"aps": {
"timestamp": 1705560370,
"event": "update",
"content-state": {
"emoji": "🍏🍑"
},
"stale-date": 1705567570
}
}
Step5: End a channel-subscribed Live Activity With Broadcast Push Notifications
You can also end the Live Activity by sending a end
push notification to the channel ID.
Host
Use HTTP/2 and TLS 1.2 or later to establish a connection between your provider server and one of the following servers.
- Development/Sandbox Environment:
api.sandbox.push.apple.com:443
- Production Environment:
api.push.apple.com:443
Request Header
- apns-push-type:
liveactivity
- :path:
/4/broadcasts/apps/<your bundleID>
(bundle ID excluding the .push-type.liveactivity suffix) - apns-priority:
5
or10
- apns-channel-id:
<Channel ID>
- apns-expiration: UNIX timestamp in seconds represents the notification expiration time. If the channel's storage policy is
No Message Stored
, this value must not be zero.
Payload
- timestamp: Current UNIX timestamp in seconds.
- event:
end
- content-state: The final dynamic data of your live activity content.
- dismissal-date:
- The UNIX timestamp when the system will remove the Live Activity from the Lock Screen after it ends.
- By default, It's four hours after the live activity ends.
- If the value is in the past, the Live Activity will immediately dismiss after it ends.
{
"aps": {
"timestamp": 1705560370,
"event": "end",
"content-state": {
"emoji": "🍑🍑"
},
"dismissal-date": 1705567570
}
}