Best Practices for iOS Live Activities

Last updated:2024-06-27

Live Activity Setup

LiveActivity is a feature introduced in iOS 16.1. With the ActivityKit framework, you can launch live activities to see real-time updates from your application on the Dynamic Island and the lock screen. For example, a sports application allows users to start a live activity and see updates at a glance during a game (refer to the iOS version features guide for details).

  • Use the ActivityKit framework in the main project to start, update, and end live activities. Use SwiftUI and WidgetKit in the widget extension to create the Live Activity interface.
  • Live activities can be started, updated, and ended not only with ActivityKit but also with remote push notifications.
  • The remote push notification update feature for LiveActivity does not support p12 certificates; users need to configure p8 certificates.

Additionally, note that Apple limits the number of LiveActivity push notifications sent per hour. If you need to frequently update LiveActivity push notifications, you need to add the NSSupportsLiveActivitiesFrequentUpdates entry in the info.plist file and set its boolean value to YES (for more information, refer to iOS LiveActivity).

Adding Live Activity Functionality to Your Project

Setup

1. Configure Info.plist

Add a key-value pair to the Info.plist file in the main project, where the key is NSSupportsLiveActivities and the value is YES;

alt text

2. Add a Widget Extension

2.1 Create a New Target

Go to File > New > Target.

2.2 Select Widget Extension

alt text

2.3 Configure the Widget Extension

Check the box for "Include Live Activity" alt text

Click Finish

Xcode will create a LiveActivity for you.

LiveActivityWidgetAttributes define the attributes of the live activity, including both mutable and immutable properties.

The LiveActivityWidgetLiveActivity struct customizes the appearance of the live activity.

alt text

Then, in the LiveActivityWidgetBundle, allow the live activity to be displayed. alt text

3. Testing

Start a live activity in the main project, listen for changes to its push token, and report the push token to EngageLab. Once reported successfully, you can use EngageLab's service to push messages to the LiveActivity on the phone.

func startLiveActivity1() { let initialContentState = MTLAAttributes.ContentState(eventStr: "begin", eventTime: 1) let activityAttributes = MTLAAttributes(name: "LiveActivity", number: 33, tag: "") do { // Create Activity let activity = try Activity.request(attributes: activityAttributes, contentState: initialContentState, pushType: PushType.token) // Listen for pushToken changes Task { for await pushtoken in activity.pushTokenUpdates { let pushtokenstr = pushtoken.map { String(format: "%02.2hhx", arguments: [$0]) }.joined() // Register liveactivity with EngageLab to update notifications via liveactivityId on the push platform MTPushService.registerLiveActivity("my_define_liveactivity_id", pushToken: pushtoken, completion: { code, liveactivityId, token, seq in print("result:\(code)") }, seq: 1) } } } catch { print("Error requesting Live Activity \(error.localizedDescription).") } }
          func startLiveActivity1() {
    
    let initialContentState = MTLAAttributes.ContentState(eventStr: "begin", eventTime: 1)
    let activityAttributes = MTLAAttributes(name: "LiveActivity", number: 33, tag: "")
    
    do {
      // Create Activity
      let activity = try Activity.request(attributes: activityAttributes, contentState: initialContentState, pushType: PushType.token)
      
      // Listen for pushToken changes
      Task {
        for await pushtoken in activity.pushTokenUpdates {
          let pushtokenstr = pushtoken.map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
          // Register liveactivity with EngageLab to update notifications via liveactivityId on the push platform
          MTPushService.registerLiveActivity("my_define_liveactivity_id", pushToken: pushtoken, completion: { code, liveactivityId, token, seq in
            print("result:\(code)")
          }, seq: 1)
        }
      }
      
    } catch {
      print("Error requesting Live Activity \(error.localizedDescription).")
    }
  }

        
This code block in the floating window
  • Starting from iOS 17.2, Apple allows using a push notification to start a live activity, which relies on a pushToStartToken. Use the pushToStartTokenUpdates function to listen for changes in the live activity's pushToStartToken and report it to EngageLab.
func pushToStart() { Task { if #available(iOS 17.2, *) { var beforeToken = "" for await pushtoken in Activity<MTLAAttributes>.pushToStartTokenUpdates { let pushtokenstr = pushtoken.map { String(format: "%02.2hhx", arguments: [$0]) }.joined() print("pushToStartToken: MTLAAttributes -> \(pushtokenstr)") if beforeToken == pushtokenstr { return } beforeToken = pushtokenstr MTPushService.registerLiveActivity("MTLAAttributes", pushToStartToken: pushtoken, completion: { code, alias, token, seq in print("register MTLAAttributes pushToStartToken result: \(pushtokenstr) result:\(code) seq:\(seq)") }, seq: seq()) } } else { // Fallback on earlier versions } } }
          func pushToStart() {
    Task {
      if #available(iOS 17.2, *) {
        var beforeToken = ""
        for await pushtoken in Activity<MTLAAttributes>.pushToStartTokenUpdates {
          
          let pushtokenstr = pushtoken.map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
          print("pushToStartToken: MTLAAttributes -> \(pushtokenstr)")
          if beforeToken == pushtokenstr {
            return
          }
          beforeToken = pushtokenstr
          
          MTPushService.registerLiveActivity("MTLAAttributes", pushToStartToken: pushtoken, completion: { code, alias, token, seq in
            print("register MTLAAttributes pushToStartToken result: \(pushtokenstr) result:\(code) seq:\(seq)")
          }, seq: seq())
        }
      } else {
        // Fallback on earlier versions
      }
    }
}

        
This code block in the floating window
在文档中心打开
Contact Sales