Adding a custom UI to Siri

When your user interacts with Siri, they aren't always looking at their device. But when they are, it's desirable that the experience a user has when using your app through Siri looks and feels a lot like when they're directly interacting with your app. One of the tools to achieve this is using custom vocabularies. You can use a vocabulary to map user- and app-specific terms to Siri's vocabulary, as you have seen in the previous section.

Another way we can customize the Siri experience is through an Intents UI Extension. Whenever you add an Intents Extension to your project, Xcode asks you if you also want to add a corresponding UI extension. If you select this checkbox, you don't have to do anything to add the UI extension, since it's already there. However, if you didn't check the checkbox, you should add a new Intents UI Extension by clicking the + icon in the list of targets for your project, just as you did when you added the Intents Extension before.

A custom user interface for an intent works a lot like other UI extensions. When you create the extension, Xcode creates a storyboard, a view controller, and a .plist file. The .plist file is expected to specify all of the intents that this UI extension can handle. In the case of Hairdressers, this is just a single intent; INSendMessageIntent. Make sure to update the Info.plist for the UI extension accordingly.

If you intend to support multiple intents, it's often a good idea to split your extension up into various extensions, while grouping intents together based on how similar they are. This will make it easier to maintain your code in the long run, and it makes it easier to reason about the way your code and extensions work.

If you open the IntentViewController file, you'll find a method named configureView(for:of:interactiveBehavior:context:completion:). This method is used to configure the UI extension's view, and you can remove it for now because you'll implement a slightly simpler version of this method later.

Since the UI extension is used for a messaging feature, it would be nice to show the Hairdressers that will end up receiving the message, and the message that they will receive. Add the following two @IBOutlet properties to the IntentViewController:

@IBOutlet var recipientsLabel: UILabel!  
@IBOutlet var messageContentLabel: UILabel!

After adding the outlets, add the following method to the IntentViewController:

func configure(with interaction: INInteraction, context: INUIHostedViewContext, completion: ((CGSize) -> Void)) {

  guard let messageIntent = interaction.intent as? INSendMessageIntent,
    let recipients = messageIntent.recipients
    else { return }


  recipientsLabel.text = recipients.map { $0.displayName }.joined(separator: ", ")
  messageContentLabel.text = messageIntent.content


  let viewWidth = extensionContext?.hostedViewMaximumAllowedSize.width ?? 0
  completion(CGSize(width: viewWidth, height: 100))
}

This implementation verifies that a message intent with recipients exists, and then populates the labels you just added accordingly. The code also determines at which width the UI should be displayed. Finally, the completion handler is called with the desired size at which Siri should display the custom UI. A value of 100 should be plenty of room to accommodate the message for now.

Next, open the storyboard file for the UI extension and add two labels. Lay them out as shown in the following screenshot. Don't forget to connect the outlets for these labels as well. You can set the text style for the message label to Body, and the recipients label can be set to Caption style:

After setting up the UI, run your UI extension instead of the intent extension, and try to send a message to one of the Hairdressers again.

You should see something that looks like the following UI: 

The cool part is that the custom UI appears. There is one problem though. The message transcript is now shown twice: Once by the extension, and once through Siri itself. To prevent this from happening, all you need to do is make our view controller conform to INUIHostedViewSiriProviding. Add this protocol to the declaration of IntentViewController, and add the following property as well:

var displaysMessage = true

By doing this, Siri is now aware that you render your own version of the message transcript, so there is no need for Siri to also show the message. Now that you know how to implement a Siri intent and provide a custom UI for it, it's time to take your Siri integration one step further, and have a look at Siri Shortcuts.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset