Performing the desired action

Once Siri understands what the user wants to do and which parameters to use, and once your app has confirmed that everything is in place to handle the user's request, the time has finally come to execute the requested action. Once this time has come, Siri calls the handle method on your intent handler.

Just like the confirm method, every intent has their own version of this method, but they all follow a similar pattern. For sending messages, the method signature is handle(intent:completion:), where the intent is an instance of INSendMessageIntent. The parameters for this method are identical to the ones in the confirmation step. The major difference is that you're now expected to handle the intent, instead of only confirming that the intent is valid.

Once you have handled the intent, you must call the completion handler with an INSendMessageIntentResponse. If everything goes well, you're expected to use a success response code. If you're unable to process the intent promptly, you must call the completion handler with an inProgress status code. Using the inProgress status code informs Siri that you're handling the intent, but it's taking a while. If you fail to handle the intent at all, you should pass a failure status to the completion handler.

Since the Hairdressers app uses Core Data to store all of its data, you will need to perform some additional steps to share data between the extension and the app. To do this, you must use the App Groups capability. App Groups associate multiple targets with a single, shared group, which allows them to access shared files or UserDefaults instances. To create an app group, you must enable the App Groups capability in the project's Capabilities tab, and provide a name for your group, as shown in the following screenshot:

When you have configured the app groups capability for your app, enable it for the MessageHairdresserIntent extension as well, and make sure to select the app group you just created to add the extension to that app group.

After doing this, you must configure the app's persistent container to use the app group for storing the database file. Add the following code to the persistentContainer computed property in PersistentHelper, right before the persistent store is loaded, to configure the persistent container properly:

let containerUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "YOUR.APP.GROUP.NAME")!
let databaseUrl = containerUrl.appendingPathComponent("Hairdressers.sqlite")
let description = NSPersistentStoreDescription(url: databaseUrl)
container.persistentStoreDescriptions = [description]

Also, make sure to add the PersistentHelper.swift file, the NSManagedObjectContext extension, and the data model in Hairdressers.xcdatamodeld, which already exist in the app target, to the extension target.

Now that the app and its Siri extension share the Core Data store, you are ready to take the message the user is trying to send and store it in the Core Data database. Add the following code to the existing extension on SendMessageIntentHandler:

func handle(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
  guard let hairdressers = intent.recipients, let content = intent.content else {
    completion(INSendMessageIntentResponse(code: .failure, userActivity: nil))
    return
  }

  let moc = PersistentHelper.shared.persistentContainer.viewContext
  moc.persist {
    for hairdresser in hairdressers {
      let message = Message(context: moc)
      message.createdAt = Date()
      message.hairdresser = hairdresser.displayName
      message.content = content
    }

    completion(INSendMessageIntentResponse(code: .success, userActivity: nil))
  }
}

All the preceding code does is create a new Message object for each recipient of the message and stores it in the Core Data database. If no recipients are found, or no message exists, the operation is considered failed. If everything works out well, the operation is completed successfully.

To test your extension, click on your app target in the top of the Xcode window and select your extension. When you attempt to run it, Xcode will ask you for an app to run it with, as shown in the following screenshot. You can pick Hairdressers if you want, but any app will do:

Before testing the extension, make sure that you have run Hairdressers at least once to make sure the app has permission to be integrated with Siri.

Even though it's pretty cool that you can now use Siri to send messages, the UI that Siri shows isn't that great. In the next section, you will learn how you can add a custom UI to your Siri intent.