iosswiftuiappdelegatesiri

iOS - AppDelegate not retrieving userActivity when Siri intent is launched


Actually making an app in swiftUI and trying to handle Siri intents to start a call in my app. I made a extension target in my project, added Siri capability and App groups in main and extension targets, my intent handler trigger the Siri request correctly at all, starting Siri and asking to make a call to some contact works perfectly, my apps gets launched and at this point is supposed to receive an activity from the intent, but nothing happen...

My intent handler looks like this:

import Intents

class IntentHandler: INExtension, INStartCallIntentHandling {
    func handle(intent: INStartCallIntent, completion: @escaping (INStartCallIntentResponse) -> Void) {
        let userActivity = NSUserActivity(activityType: NSStringFromClass(INStartCallIntent.self))
    
        guard intent.contacts?.first?.personHandle?.value != nil else {
            completion(INStartCallIntentResponse(code: .failureContactNotSupportedByApp, userActivity: userActivity))
        
            return
       }
    
        let response = INStartCallIntentResponse(code: .continueInApp, userActivity: userActivity)
    
        completion(response)
    }

    func resolveContacts(for intent: INStartCallIntent, with completion: @escaping ([INStartCallContactResolutionResult]) -> Void) {
        var contactName = ""
    
        if let contacts = intent.contacts {
            contactName = contacts.first?.displayName ?? ""
        }
    
        //This shared method is used to get contact data for completion
        DataManager.sharedManager.findContact(contactName: contactName, with: {
            contacts in
        
            switch contacts.count {
            case 1: completion([.success(with: contacts.first ?? INPerson(personHandle: INPersonHandle(value: "1800-olakase", type: .phoneNumber), nameComponents: nil, displayName: "ola k ase", image: nil, contactIdentifier: nil, customIdentifier: INPersonHandle(value: "1800-olakase", type: .phoneNumber).value))])
            case 2...Int.max: completion([.disambiguation(with: contacts)])
            default: completion([.unsupported()])
            }
        })
    }

    func confirm(intent: INStartCallIntent, completion: @escaping (INStartCallIntentResponse) -> Void) {
        let userActivity = NSUserActivity(activityType: NSStringFromClass(INStartCallIntent.self))
        let response = INStartCallIntentResponse(code: .ready, userActivity: userActivity)
    
        completion(response)
    }
}

Added INStartCallIntent to IntentsSupported in Info.plist

So, when the code in func handle(intent: INStartCallIntent, completion: @escaping (INStartCallIntentResponse) -> Void) did complete is supposed to send the NSUserActivity to my app delegate directly to func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool ... but is not triggering that function. At the moment my app can't make new calls because is not getting any userActivity to retrieve contact data.

Also I try with func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool but is not working too.

To being more specific I follow this tutorial but changing the INStartAudioCallIntent for INStartCallIntent because is deprecated. I don't know if swiftUI is the problem or not, I used @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate to add my app delegate to the swiftUI life cicle

And yes, my app has request Siri authorization and enabled. Any suggestion? I'm missing something?


Solution

  • Ok, I figured it out: The problem was that I was trying to get the NSUserActivity from the method func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool from my AppDelegate that never gets triggered, forget about that and don't follow the documentation from apple if you are using SwiftUI because is not working anymore.

    For SwiftUI you must implement .onContinueUserActivity() modifier to fetch the NSUserActivity, and from here you can do whatever you need to do. Example code:

    WindowGroup {
        ContentView().onContinueUserActivity(NSStringFromClass(INStartCallIntent.self), perform: { userActivity in
            //do something
        })
    }