User interfaces in SiriKit appear automatically when Siri decides to present them. This tutorial shows how to create and customize a user interface for a Siri Intent.
- [Teacher] With our app as it stands now, when you send a payment, there's no visual indication of who you're sending the payment to. You do see the amount of money on the screen as provided by Siri, but we don't see an image of the person. We don't see the person's name or anything. So let's look at handling an intent UI to present that information to the user. So in your intent, when everything is done and the intent is ready to be finally committed, so the last step before the user hits Send a Payment in this instance, when that button appears on the screen and Siri asks, "You have a payment to Dave for $12.
"Do you want to send it?" At that point, Siri is going to present our user interface. So let's look at designing that user interface and how to create all of the necessary connections. So inside of my intent UI, I have my intentViewController, my storyboard, and I have two images that I brought into this. So I have an image of a cat and an image of a pig. Some beautiful programmer art right there. Let's go to MainInterface.storyboard, and in here I have just that image on the screen. I've already added some constraints to it, and I've set the image view to have Aspect Fit for its content mode.
So nothing really surprising here. I just want to show you how to get the data from your intent and put it in your user interface. So we have the image, and I actually already made the connection to the code if you look inside intentViewController.swift. So this image that's an IBOutlet right here, you can make that connection just like any other connection in Xcode. You can use the assistant editor, and then a right-click and drag in just like you can with anything else. So there is nothing special there. Where you want to go is in this configure method. This is where the magic is going to happen.
We're going to write the code in here to handle the event and to set the appropriate image inside of that imageView. So I'm going to hide the left and right areas of the screen and go right inside here, right above this if statement, inside of configure. And what I want to do is I want to take the intent and I need to get that from this interaction that comes in inside of this method. So I'll take that if let intent equal interaction.intent as, so I'm going to typecast it here, INSendPaymentIntent.
So if we can typecast that to an INSendPaymentIntent, then we're good to go. That shouldn't ever be a problem, but it does make it easier to be able to access it right through here and have it be an INSendPaymentIntent, instead of having to type this and then typecast it every time. So inside of here, I'm just going to check the intent's properties. So this intent is the same object that we're setting up inside of our intent files. So remember the intent carries all that information. So if I go to intent, which is INSendPaymentIntent, I can access its properties, like currencyAmount, the note, and the payee.
So what I want to do here is check to see if the payee is a certain name. If it is, I'm going to show the appropriate image. So inside of here, I'm going to check to see if intent.payee.displayName is equal to Dave. And if it's Dave, let's show a cat; if it's not Dave, we'll show the pig. So we'll go inside of that if statement and we'll type imageView.image and set that equal to UIImage and we'll run the constructor that receives named.
And then I'll pass in cat right there. And then in the else statement, we'll do the same thing. So right below that, an else statement, copy and paste that imageView line code, and then change cat to pig. So if it's Dave, we're going to see a cat, and if it's Herman, we're going to see a pig. Now one important thing to note is that you may have noticed that this payee right here is an INPerson. So if I go above this imageView line of code to type it out with code, intent.payee.image, that gives me an INImage. So we can actually set an image for the payee.
However at this point, both in the documentation and then all of the implementations provided by Apple, there really isn't a way to get this INImage into an imageView. So we can't convert it to an UI image; it just holds image data for our contact. So while the feature is there at the time of this recording, it isn't very useful. So the best way that I've seen is actually doing it like we're doing in here. Instead of getting the images hard-coded in like this, you may be accessing that from the database. Maybe your contacts database has the name of the contact and the image file associated with that contact so you can present it.
Or maybe we're using the iOS built-in contacts database to grab that image and present it on the screen. So let's test this and see if it works in Siri. So when I test it, I'm changing it to the AppIntent UI scheme. So I'll hit the Run button, I'llrun it on Todd's App, and while it's building, I want to point out that sometimes, you need to mix up your phrasing with Siri. I've noticed that if I, say, send a payment with my app, that sometimes it works, and sometimes it doesn't work. And if I change my verbiage to send a payment on my app, then it might work.
So let's tab over to QuickTime so you can see my phone screen, and then I'll send a payment. Send $12 to Dave on Todd's App. - [Siri] Here's your Todd's App payment for $12. Do you want to send it? - [Teacher] Yes. - [Siri] Todd's App sent your payment. - [Teacher] So you can see, because I said Dave, it put that cat image in there. So we've successfully gotten the payee information and the payee's displayName into our user interface. So whenever you want to access information from an intent in your user interface, you design your user interface.
Remember, you can't use things like buttons or anything that's interactive. And then you make the connections just like you do in any other iOS application like I've done here. And then you can access that data from the intent. So inside of that interaction object that's sent into the configure method, grab that object's intent property and typecast it to whatever intent you need, and then you can use the data inside of there.
- Setting up SiriKit in a project
- Authorizing Siri for your app
- Testing the default SiriKit app
- Writing simple payment handling code
- Resolving, confirming, and handling intents
- Sending data from Siri to your app
- Using a photo intent to search for photos
- Reviewing Siri support in photo apps, VoIP calling apps, ride apps, and workout apps