Siri not calling my INExtension

Things I did:

  • created an Intents Extension target
  • added "Supported Intents" to both my main app target and the intent extension, with "INAddTasksIntent" and "INCreateNoteIntent"

  • created the AppIntentVocabulary in my main app target

  • created the handlers in the code in the Intents Extension target
class AddTaskIntentHandler: INExtension, INAddTasksIntentHandling {
    func resolveTaskTitles(for intent: INAddTasksIntent) async -> [INSpeakableStringResolutionResult] {
        if let taskTitles = intent.taskTitles {
            return taskTitles.map { INSpeakableStringResolutionResult.success(with: $0) }
        } else {
            return [INSpeakableStringResolutionResult.needsValue()]
        }
    }

    func handle(intent: INAddTasksIntent) async -> INAddTasksIntentResponse {
        // my code to handle this...

        let response = INAddTasksIntentResponse(code: .success, userActivity: nil)
        response.addedTasks = tasksCreated.map {
            INTask(
                title: INSpeakableString(spokenPhrase: $0.name),
                status: .notCompleted,
                taskType: .completable,
                spatialEventTrigger: nil,
                temporalEventTrigger: intent.temporalEventTrigger,
                createdDateComponents: DateHelper.localCalendar().dateComponents([.year, .month, .day, .minute, .hour], from: Date.now),
                modifiedDateComponents: nil,
                identifier: $0.id
            )
        }
        return response
    }
}
class AddItemIntentHandler: INExtension, INCreateNoteIntentHandling {
    func resolveTitle(for intent: INCreateNoteIntent) async -> INSpeakableStringResolutionResult {
        if let title = intent.title {
            return INSpeakableStringResolutionResult.success(with: title)
        } else {
            return INSpeakableStringResolutionResult.needsValue()
        }
    }

    func resolveGroupName(for intent: INCreateNoteIntent) async -> INSpeakableStringResolutionResult {
        if let groupName = intent.groupName {
            return INSpeakableStringResolutionResult.success(with: groupName)
        } else {
            return INSpeakableStringResolutionResult.needsValue()
        }
    }

    func handle(intent: INCreateNoteIntent) async -> INCreateNoteIntentResponse {
        do {
            // my code for handling this...

            let response = INCreateNoteIntentResponse(code: .success, userActivity: nil)
            response.createdNote = INNote(
                title: INSpeakableString(spokenPhrase: itemName),
                contents: itemNote.map { [INTextNoteContent(text: $0)] } ?? [],
                groupName: INSpeakableString(spokenPhrase: list.name),
                createdDateComponents: DateHelper.localCalendar().dateComponents([.day, .month, .year, .hour, .minute], from: Date.now),
                modifiedDateComponents: nil,
                identifier: newItem.id
            )
            return response
        } catch {
            return INCreateNoteIntentResponse(code: .failure, userActivity: nil)
        }
    }
}
  • uninstalled my app
  • restarted my physical device and simulator

Yet, when I say "Remind me to buy dog food in Index" (Index is the name of my app), as stated in the examples of INAddTasksIntent, Siri proceeds to say that a list named "Index" doesn't exist in apple Reminders app, instead of processing the request in my app.

Am I missing something?

If you use your intent phrase inside of the Xcode scheme settings (there is a place called Siri Intent Query where you can type it in), does the same thing happen?

If that's still giving you trouble, then the next thing I'd do is create a brand new test project in Xcode, give it an app name that's pretty unique, and bring in the basic outline of your Siri intent code, and make sure everything is working there. The goal of that is so that you review all of the integration steps again from a clean slate to make sure you didn't miss anything, as well as validating that once the code does run, you have a basic functional outline you can build upon for exploring the API as you build out the feature for your real app.

Jumping ahead a step, one additional thing that trips people up when debugging their intent extension is a misunderstanding of when the code runs — it is in a separate process, and so depending how you launch it, breakpoints you set for debugging may or may not be activated. A good rule of thumb for working in the multi-process world that extensions live in so to make sure you have good logging that outputs to the system log through the Logger API, and then you can use the Console app to verify your logs (and prefixing them with a unique string or emoji is a great technique for easy filtering in Console app as well). The first log I'd start with is one at the top of your INExtension handler(for:) function that acknowledges the system is looking for an intent handler, as a way of verifying that your app was consulted for handling the intent.

If you're still stuck after going through this, you can share a link to your test project code and we can go from there.

— Ed Ford,  DTS Engineer

Siri not calling my INExtension
 
 
Q