Cannot handle INPlayMediaIntent in the background

Hello everybody,

I've been struggling with implementing Siri voice shortcuts for media intents. I followed all the indications on the documentation, but when my Intent Extension (conforming to INPlayMediaIntentHandling protocol) calls handler method's completion block with INPlayMediaIntentResponseCode.handleInApp as response code, iOS doesn't wake the app in the background but asks the user to open the app.


This is my Intent Extension:


class IntentHandler: INExtension, INPlayMediaIntentHandling  {
    
    override func handler(for intent: INIntent) -> Any {
        // This is the default implementation.  If you want different objects to handle different intents,
        // you can override this and return the handler you want for that particular intent.
        
        return self
    }
    
    func handle(intent: INPlayMediaIntent, completion: @escaping (INPlayMediaIntentResponse) -> Void) {
        let response = INPlayMediaIntentResponse(code: INPlayMediaIntentResponseCode.handleInApp, userActivity: nil)
        completion(response)
    }
    
    func confirm(intent: INPlayMediaIntent, completion: @escaping (INPlayMediaIntentResponse) -> Void) {
        let response = INPlayMediaIntentResponse(code: .success, userActivity: nil)
        completion(response)
    }
    
}


I made a bare bone project to reproduce the issue: http://media.digitalia.fm/MediaShortcut.zip


Steps to Reproduce:

1 - Build and run the attached project on a device or on the simulator.

2 - Press the button to record a voice command for the shortcut.

3 - Exit the app and lock the device

4 - Invoke siri with the recorded voice command


Expected Results:

App should be awaken in the background and application(_ application: UIApplication, willContinueUserActivityWithType should be invoked so the app can begin playing the media item in the background with no user interaction.


Actual Results:

System displays the message "Sorry, there was a problem with the app" and presents a button to open the app. If the user touches the button, TouchID confirmation is asked and then the app is opened in the foreground and willContinueUserActivityWithType is invoked.


Did anybody find a way around this?


Thanks

Accepted Reply

It took me a while to figure this out too, because the documentation is unfortunately a bit lacking at the moment with regards to Shortcuts, Intents and SiriKit.


The function you're looking to implement is not

application(UIApplication, willContinueUserActivityWithType: String)

but

application(UIApplication, handle: INIntent, completionHandler: (INIntentResponse) -> Void)

In the documentation it only directly mentions INStartWorkoutIntent, but I've been using this function to handle INPlayMediaIntents and it's working.


One thing to note is that you need to create an instance of INPlayMediaIntentResponse and return that in the completion handler, rather than a INIntentResponse as the function signature shows.

Replies

It took me a while to figure this out too, because the documentation is unfortunately a bit lacking at the moment with regards to Shortcuts, Intents and SiriKit.


The function you're looking to implement is not

application(UIApplication, willContinueUserActivityWithType: String)

but

application(UIApplication, handle: INIntent, completionHandler: (INIntentResponse) -> Void)

In the documentation it only directly mentions INStartWorkoutIntent, but I've been using this function to handle INPlayMediaIntents and it's working.


One thing to note is that you need to create an instance of INPlayMediaIntentResponse and return that in the completion handler, rather than a INIntentResponse as the function signature shows.

Thank you, that's exactly what was missing!

The state of the documentation after all this time from the announcement makes everything more difficult than it should be.