Live activity integration with Adobe Experience Platform Mobile SDK mobile-live-config-sdk
The Adobe Experience Platform Mobile SDK provides built-in support for Appleās Live activity. This allows your app to display real-time, dynamic updates directly on the Lock Screen and Dynamic Island without opening the app.
-
Import the following modules: AEPMessaging, AEPMessagingLiveActivity, ActivityKit.
-
Conform to
LiveActivityAttributes, includeLiveActivityDataand aContentStateattributes. -
Use
Messaging.registerLiveActivity()after SDK initialization. -
Implement
ActivityConfigurationfor both Lock Screen and Dynamic Island interface. -
Start a Live activity locally (optional)
Live activity can be initiated either remotely through Journey Optimizer or locally within the application code.
-
Implement
LiveActivityAssuranceDebuggablefor Assurance.
Verify that the following minimum versions are installed to ensure correct configuration and compatibility.
Prerequisites:
-
iOS:
- iOS16.1 or later: Basic Live activity functionality
- iOS 17.2+: Push-to-start support
- iOS 18+: Broadcast channel support
-
Xcode: 14.0 or later
-
Swift: 5.7 or later
-
Dependencies: AEPCore, AEPMessaging, AEPMessagingLiveActivity, ActivityKit
-
AEP Mobile SDK version: iOS Messaging 5.11.0 or later
Step 1: Import required modules import
To get started, you first need to import the following modules: AEPMessaging, AEPMessagingLiveActivity, ActivityKit.
import AEPMessaging
import AEPMessagingLiveActivity
import ActivityKit
Step 2: Define your Live activity Attributes attributes
Create a struct that conforms to the LiveActivityAttributes protocol. This defines both the static data and dynamic content state for your Live activity.
The key components include:
-
liveActivityData(required) which contains Adobe Experience Platform-specific data.- For individual users: Use
LiveActivityData(liveActivityID: "unique-id") - For broadcast: Use
LiveActivityData(channelID: "channel-id")
- For individual users: Use
-
Static Attributes, custom properties specific to your use case, e.g.
restaurantName. -
ContentStatewhich defines dynamic data that can be updated during the Live activity lifecycle. It must conform toCodableandHashable. -
LiveActivityOriginenumeration specifies whether an activity was initiated locally within the app or remotely via a push-to-start notification, supported in iOS 17.2 and later. This value allows the SDK to differentiate between locally initiated and remotely triggered Live activity during data collection.
Examples
@available(iOS 16.1, *)
struct FoodDeliveryLiveActivityAttributes: LiveActivityAttributes {
// Mandatory: AEP Integration Data
var liveActivityData: LiveActivityData
// Static Attributes: Custom properties that do not change
var restaurantName: String
// Dynamic Content State: Data that can be updated
struct ContentState: Codable, Hashable {
var orderStatus: String
}
}
@available(iOS 16.1, *)
public struct LiveActivityData: Codable {
/// Unique identifier for broadcast Live activity channels
public let channelID: String?
/// Unique identifier for individual Live activity
public let liveActivityID: String?
/// Indicates local vs remote creation
public let origin: LiveActivityOrigin?
// Initializers
public init(channelID: String) // For broadcast Live activity
public init(liveActivityID: String) // For individual Live activity
}
You can also register multiple Live activity types for your app:
if #available(iOS 16.1, *) {
Messaging.registerLiveActivity(AirplaneTrackingAttributes.self)
Messaging.registerLiveActivity(FoodDeliveryLiveActivityAttributes.self)
Messaging.registerLiveActivity(GameScoreLiveActivityAttributes.self)
}
Step 3: Register Live activity register
Register your Live activity types in your AppDelegate after SDK initialization, this allows you to:
- Enables automatic push-to-start token collection (iOS 17.2+)
- Automatically collects Live activity update tokens
- Enables lifecycle management and event tracking
Example for a food delivery Live activity:
if #available(iOS 16.1, *) {
Messaging.registerLiveActivity(FoodDeliveryLiveActivityAttributes.self)
}
Step 4: Create Live activity widgets widgets
Live activity is displayed through widgets, you need to create a widget bundle and configuration:
Example for a food delivery Live activity:
@main
struct FoodDeliveryWidgetBundle: WidgetBundle {
var body: some Widget {
FoodDeliveryLiveActivityWidget()
}
}
@available(iOS 16.1, *)
struct FoodDeliveryLiveActivityWidget: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: FoodDeliveryLiveActivityAttributes.self) { context in
// Lock Screen UI
VStack {
Text("Order from \(context.attributes.restaurantName)")
Text("Status: \(context.state.orderStatus)") // possible status may include "Ordered", "Order accepted", "Preparing", "On the Way","Delivered"
}
} dynamicIsland: { context in
// Dynamic Island UI
DynamicIsland {
// Expanded UI
} compactLeading: {
// Compact leading UI
} compactTrailing: {
// Compact trailing UI
} minimal: {
// Minimal UI
}
}
}
}
Step 5: Start a Live activity locally (optional) local
While Journey Optimizer can remotely start Live activity, you can also start it locally:
Example for a food delivery Live activity:
let attributes = FoodDeliveryLiveActivityAttributes(
liveActivityData: LiveActivityData(liveActivityID: "order123"),
restaurantName: "Pizza Palace"
)
let contentState = FoodDeliveryLiveActivityAttributes.ContentState(
orderStatus: "Ordered"
)
let activity = try Activity<FoodDeliveryLiveActivityAttributes>.request(
attributes: attributes,
contentState: contentState,
pushType: .token
)
Step 6: Add debug support (optional) debug
If needed, you can debug Live activity schemas in Adobe Assurance:
Example for a food delivery Live activity:
@available(iOS 16.1, *)
extension FoodDeliveryLiveActivityAttributes: LiveActivityAssuranceDebuggable {
static func getDebugInfo() -> (attributes: FoodDeliveryLiveActivityAttributes, state: ContentState) {
return (
FoodDeliveryLiveActivityAttributes(
liveActivityData: LiveActivityData(liveActivityID: "debug-order-123"),
restaurantName: "Debug Restaurant"
),
ContentState(orderStatus: "Ordered")
)
}
}
Additional resources
For comprehensive SDK documentation and implementation details: