Start Live Activities with Push Notifications (Push-To-Start)
How to set up Live Activities on your iOS Mobile App with OneSignal
With iOS 17.2+, Live Activities can be started remotely. Also called "Push-To-Start Live Activities", they can be started and updated by a remote push notification. Live Activities can now be initiated when the app is in the foreground or background.
Setup
Requirements
- Ensure you have the latest Live Activities compatible SDK starting with iOS 5.2.0 Beta-01, more details found in OneSignal's GitHub.
1. Create a Widget Extension with “Include Live Activity”
Follow the instructions in Step 1 of our Live Activities Setup Guide.
2. Update Info list
Follow the instructions in Step 2 of our Live Activities Setup Guide.
3. Define the Static and Dynamic Data of Your Live Activity
The OneSignalLiveActivityAttributes
protocol inherits from ActivityAttributes and describes the content that appears in your Live Activity. In addition to your widget-specific static attribute data and dynamic ContentState it also defines a static onesignal attribute that contains metadata necessary for the OneSignal iOS SDK to manage the live activities lifecycle.
ExampleAppFirstWidgetAttributes.swift
import ActivityKit
import OneSignalLiveActivities
struct ExampleAppFirstWidgetAttributes: OneSignalLiveActivityAttributes {
public struct ContentState: OneSignalLiveActivityContentState{
// Dynamic stateful properties about your activity go here!
var message: String
var onesignal: OneSignalLiveActivityContentStateData?
}
// Fixed non-changing properties about your activity go here!
var name: String
var onesignal: OneSignalLiveActivityAttributeData
}
4. Add Live Activities UI to the Widget Extension
In the widget extension, the Live Activities interface code should be added in the Live Activity swift file.
import ActivityKit
import WidgetKit
import SwiftUI
struct ExampleAppFirstWidget: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: ExampleAppFirstWidgetAttributes.self) { context in
// Lock screen/banner UI goes here\VStack(alignment: .leading) {
VStack {
Spacer()
Text("FIRST: " + context.attributes.title).font(.headline)
Spacer()
HStack {
Spacer()
Label {
Text(String(context.state.message))
} icon: {
Image("onesignaldemo")
.resizable()
.scaledToFit()
.frame(width: 40.0, height: 40.0)
}
Spacer()
}
Spacer()
}
.activitySystemActionForegroundColor(.black)
.activityBackgroundTint(.white)
} dynamicIsland: { _ in
DynamicIsland {
// Expanded UI goes here. Compose the expanded UI through
// various regions, like leading/trailing/center/bottom
DynamicIslandExpandedRegion(.leading) {
Text("Leading")
}
DynamicIslandExpandedRegion(.trailing) {
Text("Trailing")
}
DynamicIslandExpandedRegion(.bottom) {
Text("Bottom")
// more content
}
} compactLeading: {
Text("L")
} compactTrailing: {
Text("T")
} minimal: {
Text("Min")
}
.widgetURL(URL(string: "http://www.apple.com"))
.keylineTint(Color.red)
}
}
}
5. Invoke the setup() in the AppDelegate
OneSignal makes this activity-id
handoff seamless by providing a new function OneSignal.LiveActivities.setup
that manages the life cycle of the Live Activity for the application. This includes listening for both pushToStart token updates and pushToUpdate token updates. When using this method, the application does not need to listen for pushToStart token updates, the starting of a Live Activity, or update token updates.
In the AppDelegate, ensure you've imported OneSignalLiveActivities
and call the setup method.
AppDelegate.swift
if #available(iOS 16.1, *) {
OneSignal.LiveActivities.setup(ExampleAppFirstWidgetAttributes.self)
}
6. Start the Live Activity with a remote push notification
The included activity_type
param must be a stringified representation of the attributes struct used to define the Live Activity. In this case ExampleAppFirstWidgetAttributes
is added as a path parameter like so : /activities/activity/ExampleAppFirstWidgetAttributes
Additionally, a unique activity_id
value must be created and used to represent the real-time event. In the example below, we specify my-example-activity-id
. However, in a production setting, it is highly recommended to append a random unique value such as UUID to guarantee uniqueness.
There are a handful of parameters that must be included when creating the Push-to-Start Notification:
event_attributes
is an object data structure that maps to the static attributes data defined in the widget struct.event_updates
is an object data structure that maps to the dynamic ContentState data defined in the widget struct.- An audience targeting parameter (
included_segments
,excluded_segments
,include_subscription_ids
, filters) - To avoid surprising users with a sudden Live Activity, include headings and content fields to alert the user when the Live Activity starts.
curl --request POST \ --url "http://onesignal.com/api/v1/apps/APP_ID/activities/activity/ExampleAppFirstWidgetAttributes" \ --header "Authorization: Basic REST API KEY" \ --header "accept: application/json" \ --header "content-type: application/json" \ --data '{ "included_segments: ["Subscribed Users"], "activity_id": "my-example-activity-id", "attributes": { "foo": "bar" }, "event_updates": { "message": "hello" }, "name": "hello" }'
7. Update a Live Activity
To ensure that update notifications are sent to a Live Activity that has actually been started, it is important to use the same activity-id
in both the start notification and the update notification. Include the same activity_id
when making the API request along with the next iteration of event updates (or content state).
curl --request POST \
--url https://onesignal.com/api/v1/apps/app_id/live_activities/my-example-activity-id/notifications \
--header 'Authorization: Basic YOUR_REST_API_KEY' \
--header 'Content-Type: application/json' \
--header 'accept: application/json' \
--data '
{
"event": "update",
"event_updates": {
"message": "The content available to the Live Activity from the defined ContentState."
},
"name": "Internal OneSignal Notification Name",
"contents": {
"en": "English Message"
},
"headings": {
"en": "English Message"
},
"sound": "beep.wav",
"stale_date": 1695760785,
"dismissal_date": 1703505600,
"priority": 10
}
Follow our Live Activity Server API reference for instructions and examples on making a request to start a Live Activity remotely.
Updated 21 days ago