Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live activities #4908

Merged
merged 29 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
18a89e3
WIP
josh-mccrowell-braze Feb 24, 2023
deb4407
End of day commit
josh-mccrowell-braze Feb 25, 2023
616b491
Apply suggestions from code review
josh-mccrowell-braze Feb 27, 2023
5ca2d25
Updated endpoint example
josh-mccrowell-braze Feb 27, 2023
8d866c3
Update _docs/_developer_guide/platform_integration_guides/swift/live_…
josh-mccrowell-braze Feb 27, 2023
6e92804
WIP
josh-mccrowell-braze Feb 27, 2023
1bfe63d
Merge branch 'live-activities' of https://github.com/braze-inc/braze-…
josh-mccrowell-braze Feb 27, 2023
8ee0928
End of day update
josh-mccrowell-braze Feb 27, 2023
3079824
Merge branch 'develop' into live-activities
josh-mccrowell-braze Feb 27, 2023
de00ef8
Fixing broken links
josh-mccrowell-braze Feb 27, 2023
efbf33c
Merge branch 'live-activities' of https://github.com/braze-inc/braze-…
josh-mccrowell-braze Feb 27, 2023
a86da72
Hiding the endpoint from the sidebar
josh-mccrowell-braze Feb 27, 2023
3e5eb27
Update _docs/_developer_guide/platform_integration_guides/swift/live_…
josh-mccrowell-braze Feb 28, 2023
7813d24
Update _docs/_developer_guide/platform_integration_guides/swift/live_…
josh-mccrowell-braze Feb 28, 2023
795e498
Update _docs/_developer_guide/platform_integration_guides/swift/live_…
josh-mccrowell-braze Feb 28, 2023
f689847
Update _docs/_developer_guide/platform_integration_guides/swift/live_…
josh-mccrowell-braze Feb 28, 2023
42cdbea
Responding to comments from GitHub reviewers
josh-mccrowell-braze Feb 28, 2023
ffe6a2f
Update _docs/_api/endpoints/messaging/live_activity/update.md
josh-mccrowell-braze Feb 28, 2023
56bb3aa
Apply suggestions from code review
josh-mccrowell-braze Feb 28, 2023
084a197
Apply suggestions from code review
josh-mccrowell-braze Feb 28, 2023
5feb7ed
Apply suggestions from code review
josh-mccrowell-braze Feb 28, 2023
6988627
Apply suggestions from code review
josh-mccrowell-braze Feb 28, 2023
eeef053
Update _docs/_developer_guide/platform_integration_guides/swift/live_…
josh-mccrowell-braze Feb 28, 2023
f5caf81
Update _docs/_developer_guide/platform_integration_guides/swift/live_…
josh-mccrowell-braze Feb 28, 2023
ccc6b92
Apply suggestions from code review
josh-mccrowell-braze Feb 28, 2023
f722cb7
Update _docs/_api/endpoints/messaging/live_activity/update.md
josh-mccrowell-braze Feb 28, 2023
951c882
Added request body
josh-mccrowell-braze Feb 28, 2023
a806b2d
Update _docs/_developer_guide/platform_integration_guides/swift/live_…
josh-mccrowell-braze Feb 28, 2023
66a7612
Updated notification and removed answered questions
josh-mccrowell-braze Feb 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions _docs/_api/endpoints/messaging/live_activity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
nav_title: Live Activity
config_only: true
hidden: true
---
105 changes: 105 additions & 0 deletions _docs/_api/endpoints/messaging/live_activity/update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
hidden: true
nav_title: "POST: Update Live Activity"
article_title: "POST: Update Live Activity"
search_tag: Endpoint
page_order: 1
josh-mccrowell-braze marked this conversation as resolved.
Show resolved Hide resolved

layout: api_page
page_type: reference
description: "This article outlines details about the Update Live Activity endpoint."

---
{% api %}
# Update Live Activity
{% apimethod post %}
/messages/live_activity/update
{% endapimethod %}

Use this endpoint to update and end [Live Activities](({{site.baseurl}}/developer_guide/platform_integration_guides/swift/live_activities/)) displayed by your iOS app.

Before using this endpoint, you must register an activity with the Braze Swift SDK using the [`launchActivity`](https://braze-inc.github.io/braze-swift-sdk/documentation/brazekit/braze/liveactivities-swift.class/launchactivity(pushtokentag:activity:fileid:line:)) method. Required request parameters will be defined during this step. Refer to [Live Activities]({{site.baseurl}}/developer_guide/platform_integration_guides/swift/live_activities/) for more information on registration.

## Rate limit

{% multi_lang_include rate_limits.md endpoint='default' category='message endpoints' %}

josh-mccrowell-braze marked this conversation as resolved.
Show resolved Hide resolved
## Request body

```json
{
"app_id": "(required, string) App API identifier retrieved from the Developer Console.",
"activity_id": "(required, string) When you register your Live Activity using launchActivity, you use the pushTokenTag parameter to name the Activity’s push token to a custom string. Set activity_id to this custom string to define which Live Activity you want to update.",
"content_state": "(required, object) You define the ContentState parameters when you create your Live Activity. Pass the updated values for your ContentState using this object. The format of this request must match the shape you initially defined.",
"end_activity": "(optional, boolean) If true, this request ends the Live Activity.",
"dismissal_date": "(optional, datetime in ISO-8601 format) the time to remove the Live Activity from the user’s UI. If this time is in the past, the Live Activity will be removed immediately.",
"stale_date": "(optional, datetime in ISO-8601 format) when the Live Activity content is marked as outdated in the user’s UI.",
"notification": "(optional, object ) include an apple_push object to define a push notification that will also be displayed with this update."
}
```

## Request parameters

| Parameter | Required | Data Type | Description |
|---|---|---|---|
| `app_id` | Required | String | App [API identifier]({{site.baseurl}}/api/identifier_types/#the-app-identifier) retrieved from the **Developer Console**. |
| `activity_id` | Required | String | When you register your Live Activity using [`launchActivity`](https://braze-inc.github.io/braze-swift-sdk/documentation/brazekit/braze/liveactivities-swift.class), you use the `pushTokenTag` parameter to name the Activity's push token to a custom string.<br><br>Set `activity_id` to this custom string to define which Live Activity you want to update. |
| `content_state` | Required | Object | You define the `ContentState` parameters when you create your Live Activity. Pass the updated values for your `ContentState` using this object.<br><br>The format of this request must match the shape you initially defined. |
| `end_activity` | Optional | Boolean | If `true`, this request ends the Live Activity. |
| `dismissal_date` | Optional | Datetime <br>([ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) string) | This parameter defines the time to remove the Live Activity from the user's UI. If this time is in the past, the Live Activity will be removed immediately. |
| `stale_date` | Optional | Datetime <br>([ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) string) | This parameter tells the system when the Live Activity content is marked as outdated in the user's UI. |
| `notification` | Optional | Object | Include an [`apple_push`]({{site.baseurl}}/api/objects_filters/messaging/apple_object/) object to define a push notification that will also be displayed with this update. |
{: .reset-td-br-1 .reset-td-br-2 .reset-td-br-3 .reset-td-br-4}

## Example request

```json
curl --location --request POST 'https://rest.iad-01.braze.com/messages/live_activity/update \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {YOUR-REST-API-KEY}' \
--data-raw '{
"app_id": "{YOUR-APP-API-IDENTIFIER}",
"activity_id": "live-activity-1",
"content_state": {
"teamOneScore": 2,
"teamTwoScore": 4
},
"end_activity": false,
"dismissal_date": "2023-02-28T00:00:00+0000",
"stale_date": "2023-02-27T16:55:49+0000",
"notification": {
"alert": {
"body": "It's halftime! Let's look at the scores",
"title": "Halftime"
}
}
}
```

## Response

There are two status code responses for this endpoint: `201` and `4XX`.

### Example success response

A `201` status code is returned if the request was formatted correctly and we received the request. The status code `201` could return the following response body.

```json
{
"message": "success"
}
```

### Example error response

The `4XX` class of status code indicates a client error. Refer to the [API errors and responses article]({{site.baseurl}}/api/errors/) for more information about errors you may encounter.

The status code `400` could return the following response body.

```json
{
"error": "\nProblem:\n message body does not match declared format\nResolution:\n when specifying application/json as content-type, you must pass valid application/json in the request's 'body' "
}
```

{% endapi %}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ The endpoint may also return an error code and a human-readable message in some

Most endpoints at Braze have a rate limit implementation that will return a 429 response code if you have made too many requests. The transactional sending endpoint works differently -- if you exceed your allotted rate limit, our system will continue to ingest the API calls, return success codes, and send the messages, however those messages may not be subject to the contractual SLA for the feature. Please reach out if you need more information about this functionality.

### Transactional HTTP event postback
### Transactional HTTP event postback

All transactional emails are complemented with event status postbacks sent as an HTTP request back to your specified URL. This will allow you to evaluate the message status in real-time and take action to reach the user on another channel if the message goes undelivered, or fallback to an internal system if Braze is experiencing latency.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
---
hidden: true
nav_title: Live Activities
article_title: Live Activities for iOS
platform: Swift
page_order: 8
description: "This article covers using Braze to manage your Live Activities tokens."

---

# Live Activities for iOS

{% alert important %}
Live Activities are currently in early access. Contact your Braze account manager if you're interested in participating.
{% endalert %}

Live Activities are persistent, interactive notifications displayed on your lock screen, allowing you to keep an eye on things in real-time. Because they appear on the lock screen, Live Activities ensure that your notifications won't be missed. Because they're persistent, you can display up-to-date content to your users without even having them unlock their phone.

As a developer, you can use Braze to manage your Live Activity lifecycles, make calls to the Braze REST API to make Live Activity updates, and have all subscribed devices receive the update as quickly as possible. And, because you're managing Live Activities through Braze, you can use them in tandem with your other messaging channels&mdash;push notifications, in-app messages, Content Cards&mdash;to drive adoption.

## Prerequisites

{% sdk_min_versions swift:5.11.0 %}
KellieHawks marked this conversation as resolved.
Show resolved Hide resolved

Additional prerequisites include:
* Live Activities are only available for iPhones on iOS 16.1 and later. To use this feature, ensure that your project is targeting this iOS version.
* The `Push Notification` entitlement must be added under **Signing & Capabilities** in your Xcode project.

## Implementing a Live Activity

To manage the lifecycle of a Live Activity, follow these four steps.

1. [Create the Live Activity.](#developing) Develop the Live Activity UI using WidgetKit and SwiftUI. Initialize a Live Activity object with the relevant data models for your static and dynamic states.<br><br>

2. [Register the Live Activity](#registering) Register a Live Activity with the Braze SDK using the [`launchActivity`](https://braze-inc.github.io/braze-swift-sdk/documentation/brazekit/braze/liveactivities-swift.class/launchactivity(pushtokentag:activity:fileid:line:)) method with the Live Activity object and unique activity tag.<br><br>

3. [Update the Live Activity](#updating) Publish updates to the Live Activity using the Braze [`/messages/live_activity/update`]({{site.baseurl}}/api/endpoints/messaging/live_activity/update) API endpoint.<br><br>

4. [End the Live Activity](#ending) End a Live Activity for all recipients by publishing an update to [`/messages/live_activity/update`]({{site.baseurl}}/api/endpoints/messaging/live_activity/update) with the parameter `"end_activity": true`.

## Step 1: Developing your Live Activity {#developing}

First, ensure that you have followed [Displaying live data with Live Activities][3] in Apple’s documentation to set up Live Activities in your iOS application. As part of this task, make sure you include `NSSupportsLiveActivities` set to `YES` in your `Info.plist`.

Because the exact nature of your Live Activity will be specific to your business case, you will need to set up and initialize the [Activity][4] objects. Importantly, you will define:
* `ActivityAttributes`: This protocol defines the static (unchanging) and dynamic (changing) content that will appear in your Live Activity.
* `ActivityAttributes.ContentState`: This type defines the dynamic data that will be updated over the course of the activity.

You will also use SwiftUI to create the UI presentation of the lock screen and Dynamic Island on supported devices.
josh-mccrowell-braze marked this conversation as resolved.
Show resolved Hide resolved

Make sure you're familiar with Apple's [prerequisites and limitations][2] for Live Activities, as these constraints are independent from Braze.

{% alert note %}
If you expect to send frequent pushes to the same Live Activity, you can avoid being throttled by Apple's budget limit by setting `NSSupportsLiveActivitiesFrequentUpdates` to `YES` in your `Info.plist` file. For more details, refer to the [`Determine the update frequency`](https://developer.apple.com/documentation/activitykit/updating-and-ending-your-live-activity-with-activitykit-push-notifications#Determine-the-update-frequency) section in the ActivityKit documentation.
{% endalert %}

### Example

Let's imagine that we want to create a Live Activity to give our users updates for the Superb Owl show, where two competing wildlife rescues are given points for the owls they have in residence. For this example, we have created a struct called `BrazeActivityAttributes`, but you may use your own implementation of `ActivityAttributes`.

```swift
#if canImport(ActivityKit)
import ActivityKit
#endif

@available(iOS 16.1, *)
struct BrazeActivityAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
var teamOneScore: Int
var teamTwoScore: Int
}

var gameName: String
var gameLocation: String
}
```

## Step 2: Registering a Live Activity {#registering}

Next, you will use Braze methods to track and manage your Live Activities.

Updates to a Live Activity can be sent using ActivityKit (Apple’s framework for managing a Live Activity) or remote push notifications. In this instance, you will use ActivityKit to get a push token, which the Braze SDK can manage for you. This allows you to update Live Activities through the Braze API, as Braze will send the push token to the Apple Push Notification service (APNs) on the backend.

1. Create an instance of your Live Activity implementation using Apple’s ActivityKit APIs.
2. Set the `pushType` parameter as `.token`.
3. Pass in the Live Activities `ActivitiesAttributes` and `ContentState` you defined.
4. Register your activity with your Braze instance by passing it into [`launchActivity(pushTokenTag:activity:)`][5]. The `pushTokenTag` parameter is a custom string you define. It should be unique for each Live Activity you create.

Once you have registered the Live Activity, the Braze SDK will extract and observe changes in the push tokens.

### Example

For our example, we’ll create class called LiveActivityManager as an interface for our Live Activity objects. Then, we'll set the `pushTokenTag` to `"live-activity-1"`.

```swift
import BrazeKit

#if canImport(ActivityKit)
import ActivityKit
#endif

class LiveActivityManager {

@available(iOS 16.2, *)
func createActivity() {
let activityAttributes = BrazeActivityAttributes(gameName: "Superb Owl LVII", gameLocation: "Glendale, Arizona")
let contentState = BrazeActivityAttributes.ContentState(teamOneScore: "0", teamTwoScore: "0")
let activityContent = ActivityContent(state: contentState, staleDate: nil)
if let activity = try? Activity.request(attributes: activityAttributes,
content: activityContent,
// Setting your pushType as .token allows the Activity to generate push tokens for the server to watch.
pushType: .token) {
// Register your Live Activity with Braze using the pushTokenTag
AppDelegate.braze?.liveActivities.launchActivity(pushTokenTag: "live-activity-1",
activity: activity)
}
}

}
```

### Resuming Live Activity tracking

You will need to ensure that Braze tracks your Live Activity upon app launch.

To do this:
1. Open your `AppDelegate` file.
2. Import the `ActivityKit` module if it’s available.
3. Call [`resumeActivities(ofType:)`][6] in `application(_:didFinishLaunchingWithOptions:)` for all `ActivityAttributes` types you have registered in your application.

This allows Braze to resume tasks to track push token updates for all active Live Activities. Note that if a user has explicitly dismissed the Live Activity on their device, it is considered removed, and Braze will no longer track it.

#### Example

```swift
import UIKit
import BrazeKit

#if canImport(ActivityKit)
import ActivityKit
#endif

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

static var braze: Braze? = nil

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {

if #available(iOS 16.1, *) {
Self.braze?.liveActivities.resumeActivities(
ofType: Activity<BrazeActivityAttributes>.self
)
}

return true
}
}
```

## Step 3: Updating a Live Activity {#updating}

The [`/messages/live_activity/update`][1] endpoint allows you to update a Live Activity through push notifications passed through the Braze REST API. Use this endpoint to update your Live Activity's `ContentState`.

See the [`/messages/live_activity/update`][1] endpoint documentation for full details.

## Step 4: Ending a Live Activity {#ending}

When a Live Activity is active, it is shown on both a user's lock screen and Dynamic Island. There are a few different ways for a Live Activity to end and be removed from a user's UI.

josh-mccrowell-braze marked this conversation as resolved.
Show resolved Hide resolved
* **User dismissal**: A user can manually dismiss a Live Activity.
* **Time out**: After a default time of 8 hours, iOS will remove the Live Activity from the user's Dynamic Island. After a default time of 12 hours, iOS will remove the Live Activity from the user's lock screen.
* **Dismissal date**: You can provide a datetime for a Live Activity to be removed from a user's UI prior to time out. This is defined either in the Activity's `ActivityUIDismissalPolicy` or using the `dismissal_date` parameter in requests to the `/messages/live_activity/update` endpoint.
* **End activity**: You can set `end_activity` to `true` in a request to the `/messages/live_activity/update` endpoint to immediately end a Live Activity.
josh-mccrowell-braze marked this conversation as resolved.
Show resolved Hide resolved

See the [`/messages/live_activity/update`][1] endpoint documentation for full details.

[1]: {{site.baseurl}}/api/endpoints/messaging/live_activity/update
[2]: https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities#Understand-constraints
[3]: https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities
[4]: https://developer.apple.com/documentation/activitykit/activityattributes
[5]: https://braze-inc.github.io/braze-swift-sdk/documentation/brazekit/braze/liveactivities-swift.class
[6]: https://braze-inc.github.io/braze-swift-sdk/documentation/brazekit/braze/liveactivities-swift.class/resumeactivities(oftype:)
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,19 @@ Add the following `<link>` tag to your website's `<head>` element pointing to wh

Your website must have a service worker file that imports the Braze service-worker library, as described in our [web push integration guide][service-worker].

### Step 4: Add to homescreen {#add-to-homescreen}
### Step 4: Add to home screen {#add-to-homescreen}

Unlike major browsers like Chrome and Firefox, you are not allowed to request push permission on Safari iOS/iPadOS unless your website has been added to the user's homescreen.
Unlike major browsers like Chrome and Firefox, you are not allowed to request push permission on Safari iOS/iPadOS unless your website has been added to the user's home screen.

The [Add to Homescreen][add-to-homescreen] feature lets users bookmark your website, adding your icon to their valuable homescreen real estate.
The [Add to Homescreen][add-to-homescreen] feature lets users bookmark your website, adding your icon to their valuable home screen real estate.

![An iphone showing options to bookmark a website and save to the homescreen][1]{: style="max-width:40%"}
![An iphone showing options to bookmark a website and save to the home screen][add-to-homescreen-img]{: style="max-width:40%"}

### Step 5: Show the native push prompt {#push-prompt}
Once the app has been added to your homescreen you can now request push permission when the user takes an action (such as clicking a button). This can be done using the [`requestPushPermission`][requestPushPermission] method, or with a [no-code push primer in-app message][push-primer].
Once the app has been added to your home screen you can now request push permission when the user takes an action (such as clicking a button). This can be done using the [`requestPushPermission`][requestPushPermission] method, or with a [no-code push primer in-app message][push-primer].

{% alert note %}
Once you accept or decline the prompt, you'll need to delete and reinstall the website to your homescreen to be able to show the prompt again.
Once you accept or decline the prompt, you'll need to delete and reinstall the website to your home screen to be able to show the prompt again.
{% endalert %}

![A push prompt asking to "allow" or "don't allow" Notifications][2]{: style="max-width:40%"}
Expand Down