skip to Main Content

When implementing lock screen live activity widget for debugging purposes I had a button which runs startLiveActivity() function, app runs normaly widget appears totally functioning.

However I need this activity widget to appear whenever the app receives a remote push notification when the app is killed or in background, but it is appearing only when app is in foreground which doesn’t really help the case here.

class LiveActivityHelper: ObservableObject {
    
    static var shared = LiveActivityHelper()
    
    @Published var activity: Activity<Attributes>? = nil

    func startLiveActivity() {
        
        let state = Attributes.ContentState()
        
        activity = try? Activity<Attributes>.request(attributes: Attributes(), contentState: state, pushType: nil)

    }

I tried running the startLiveActivity() function from appDelegate’s didReceiveRemoteNotification:

func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse) async {
        
        LiveActivityHelper.shared.startLiveActivity()
}

And from a notification extension I have:

class NotificationService: UNNotificationServiceExtension, UNUserNotificationCenterDelegate {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {

    ...
    LiveActivityHelper.shared.startLiveActivity()

All these approaches lead to the same result, the widget appearing only when the app is opened.

Apple’s documentation included updating the widget from a remote notification but not how to start it using that approach.

2

Answers


  1. A Live Activity can only be started while the app is in foreground, because its purpose is to track a user-initiated feature, based on documentation.

    Send your push notification, have your user open your app with it, then start the activity. Your desired flow is explicitly stated to be unsupported.

    Login or Signup to reply.
  2. Using actionable notification type can help you by guiding user for tap and hold it to add:

    func userNotificationCenter(_ center: UNUserNotificationCenter,
           didReceive response: UNNotificationResponse,
           withCompletionHandler completionHandler: 
             @escaping () -> Void) {
           
       // Get the details from the original notification.
       let userInfo = response.notification.request.content.userInfo
            
       // Perform the task associated with the action.
       switch response.actionIdentifier {
       case "liveActivity":
          initiateLiveActivity(with: userInfo)
          break
    
       // Handle other actions…
       default:
          break
       }
        
       // Always call the completion handler when done.    
       completionHandler()
    }
    

    For remote push notifications, you need to prepare valid payload for this. More details about actionable notification from Apple documentation.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search