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?
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
})
}