Hello hello my code pals my friends my amigos in this video we're going to go ahead and create a Siri
kit intense app extension.
And we're also going to configure it so that it's good to go with a workout style app.
So let's go ahead and let's pull over on our project here and what we need to do first is to create
that intense app extension and so to do that what we're going to do is go up to the very top of our
app here and click File New and then select target.
OK.
Now there's a bunch of different things you can select here and those are for different topics but we
need to focus on an intense extension K and that's a sirra kit intense extension so go ahead and click
on it and what we need to give it a name and so I'm just going to actually call this intent handler.
OK.
And it's basically going to you know handle whatever happens in our intents.
So its name is intent handler leave all this information the same.
But if this box is ticked include UI extension and ticket we do not want it because this course is not
going to cover the UI extensions for the intent or the contents.
But you can definitely do that if you want to dive into that.
For now though were going to ticket and move on.
So click Finish and its going to go ahead and ask you if you want to activate the content handler scheme
click activate.
Yes because you do want to do that and you'll notice there's another little project over here in our
main project.
If you open it up you'll see there are two different files here.
One says intent.
The other is Infocom pelisse that has its own info up list file and the interesting thing is that when
we create this it assumes that we're making a messaging app and all this example code here is Regards
in regards to a messaging app.
And so I'm actually going to go ahead and just get rid of these comments and we're actually going to
delete everything in here except for the class itself.
So delete all this because these are all specific functions for messaging and also these protocols that
we are extending.
And go ahead and just conform to I-N start work out in 10 handly.
OK this is the delegate that handles the starting of a workout.
And of course we need to handle our intent and that's why we're using the intent handler protocol for
starting a workout.
Now that's great.
But let's go ahead and let's pause for a sec and dive over into our info the populist file.
So go into that and you'll notice this looks pretty standard except down here at the bottom there's
a little dictionary that says an extension pop that open and you'll see there is an N S extension point
identifier and s extension principle class.
Don't do anything with those.
Those are fine by default but we need to dive into the extension attributes.
And there are two arrays in here.
One is called intent supported and one is called intense restricted while locked.
Now they do exactly what you would think intent supported is basically going to be what Syrie kit intense
like start a workout and a workout Pazz Pozza workout add item 2 to do list for quest to ride which
intense are going to be supported regardless of if the device is locked or not and the intense restricted
is going to say okay which ones are going to be restricted while the phone is locked now.
You know sending payments while the phone is locked is probably not a good idea because anyone can pick
up your phone and say hey send me five hundred dollars and it would send them $500 because it's you
know not locked down with security.
So if you open this up there's actually nothing in here.
And so we don't need to put anything in there but it does need to stay.
So just leave it there.
But if you pop open intense supported you'll notice that these are the ones that were related to messaging
from the swift file so we can actually get rid of all of these.
So just select them one by one and delete all three.
Then we're going to just create an item inside by clicking that plus icon and item 0 is an OK name but
we need to go ahead and use the proper intent.
And we want to start a workout.
So we're going to type and start workout and press enter.
And that is the intent that we want to support.
Now if we were going to support pausing workouts we could say I can pause workout and I'm not just doing
this from memory I do.
Well I am but I do know that I got these from Apple's documentation.
If we wanted to support the ending of a workout we could support an end workout.
OK.
Now the interesting thing is that you need to know is let's say that you know speak something to Siri
you say Hey Siri blah blah blah.
And let's say that it's not exactly sure what you meant.
Like maybe you said something that was a bit ambiguous it's not sure if you want to pause or end the
workout like if you say you know stop my workout.
What it's actually going to do is it's going to look through intense supported.
And it's going to choose the top most item with a higher priority than the second and the second with
a higher priority than the third.
So put these in the order that you expect you know you're in tends to come in as.
Now for our app I'm going to actually delete pause and work out.
And we're just going to keep start work out.
But that's good to know that the order actually does impact how Siri might look through and make requests
based on what you say.
Now I forgot this I N stands for intent.
And we actually need to you know explicitly specify that this is an intent.
So it's called I and start work out intent.
OK.
And that is it guys that's that's there our intent handler is here and now we're going to write the
code to help us actually handle what happens when we speak to Siri.
And there is one big function that we really care about since we're starting a workout and check it
out if we type handle.
There's one called handle intent.
I start work out intent and that's the one we just set up in our info that pilots file so select it.
And as you can see when this is called in intent is passed in and there is a completion handler where
we pass the response out.
OK.
And it's escaping so whenever we call this later we can escape that value out or wherever a series picks
it up.
So inside the code here we're going to go ahead and print out a little statement basically saying what
intent we're actually using.
So we're going to just say print.
And here we go.
We're going to print out start work out intent.
OK.
And we're going to put a comma and pass in the intent and this is going to go ahead and print out everything
like if I said start a workout for five minutes it would print out the time it would print out the type
of workout it would print out all the relevant information for that particular workout and that's important
because we need to use that later to display the data on the screen.
Next up we're going to go ahead and essentially create a property that holds the spoken phrase what
it thinks we said you know start a walking workout.
It's going to say walk.
Started running workout is going to say run and that we can actually pull that spoken phrase out of
the intent and I'll show you why we need to use this in just a second.
But for now go ahead and use guard.
Because it is optional type.
Guard let spoken phrase that's going to be equal to intent dot workout name which is optional.
Spoken phrase.
OK.
And that's the phrase that Siri is identifying that we are wanting to perform.
Now we're going to set it as that.
But if there is not or else we're going to call our completion handler and we're going to basically
say hey it's complete but it failed because there was no matching workout.
So go ahead and call completion.
And as you can see it's expecting a parameter of type II and start work out.
Intent response.
So let's give it that eye and start work out in response.
And we're going to go ahead and pass in a code and user activity.
OK we'll talk about user activity in just a second.
So what we're going to do is we're going to go ahead and pass in like I said Dot failure no matching
workout.
OK.
So that basically means if I said you know start a workout for five minutes it's going to say I don't
know what workout you meant there's no matching workout by that name or if I said start a cycle workout
will say there's no work out by that name and user activity.
This is basically an item that contains everything the user is doing at the moment.
And so what we can do this stuff is really cool because it actually is going to fill user activity automatically
for us.
We don't even need to create a property for it.
So I'm actually going to set it to nil because at this point if there is no spoken phrase it doesn't
really matter what we were doing because it's not going to work.
At the end of course since this is an else statement we're going to go ahead and return out of our guard.
So we don't get a crash.
So we now have a spoken phrase property and this is where it's really important.
Now the workout intent can handle cycling it can handle swimming it can handle running walking all kinds
of things.
We want to lock this app down just so that it can handle walking and running just to make it simple
and a way you can do that as by typing if spoken phrase is equal to walk or spoken phrase is equal to
run.
We're going to go ahead and basically call the completion handler saying that we you know this is a
good workout.
Let's open the app and show the data.
So call the completion handler and that's going to be of type and start work out response.
Now let's think about if I say start a cycle work out for 20 minutes and my app is not supposed to support
cycle workouts that's where this block is going to come into play.
So we can type completion and passen and I and start work out intent response with a code like so.
Failure no matching workout right just like we did above.
So if there's no matching spoken phrase we're going to fail because it doesn't match if our phrase doesn't
match the two cases that we really care about.
We're gonna say failure no matching workout and user activity can be nil because it doesn't really matter
what happens at that point.
Now if we get to this point that means we've done it successfully we have successfully you know suggests
that all a workout of type Walker of type run.
So let's go ahead and let's pass in a code here.
Now there's a lot of them.
Failure failure no matching workout failure or ongoing workout failure requiring app launch handle and
app ready unspecified.
The one we want is handle an app meaning we want to handle the intent in our app instead.
So if we pass handle an app it's going to say hey sear or leg day is going to continue with your request
and it'll open up in our day app which is pretty cool.
Now for user activity what we're actually going to do.
I'm actually gonna go ahead and create a property here called user activity and it's going to be whip's
activity and it's going to be of type and s user activity and that's user activity and it's going to
be optional and I'm going to set it to be nil from the get go.
And you know what I'm actually gonna go ahead and copy this.
Instead of saying nil I'm just going to pass in user activity every time because it's either going to
be nil or have a value.
And the cool thing is when we actually do this when we call the intent user activity is going to be
passed of value.
And so that's why we're going to pass it in here.
So that's that's the reason for that.
Now it says that it's never.
Oh OK.
We're going to just change it to a lot because we're never actually we're not.
We are not modifying it.
And so we're going to go ahead and actually set it like so.
So let's think what do we need to do next.
We are handling the intent.
Our intent handler here is done.
We have set it up to focus on the eye and start work out intent.
That's awesome.
I think we should go test this out personally.
But there's one thing we got to do.
It's not going to know to actually call this other target unless we specify it in the app.
Delegate Okay.
So go ahead and open your app delegate here and there is a function that we can call or I guess a delegate
method rather called continue user activity.
OK.
And this is where that user activity is going to be created and then passed into our extension.
OK.
So what we're going to do is below did finish launching.
We're going to call continue user activity and it's right here it's this long one application continue
USIA activity restauration handler.
OK.
That's what we're going to call.
And in order to actually access the intent and all the silicates stuff we're going to go ahead and import
intense like so.
And now we're going to go ahead and actually call guard let intent.
And we're going to set it to be equal to the user activity.
OK.
Because that's from here.
Continue user activity.
We're going to pass that in to interaction.
We're going to get the interaction from that which is of type II and interaction.
OK.
Now it says right here when Siri Kitt launches your app it fills this property with the intent and response
information that you're launching for your app so we can go ahead and call DOT intent and we can actually
get out the exact intent that we wanted which we know is of type and start work out intent.
So we should cast that is that I then start work out intent OK but since this is Gardley we should call
else meaning if that doesn't work we're going to go ahead and print.
And this is just the message for our self saying app delegate.
Start work out intent false meaning it didn't work then we're going to go ahead and return false because
this function is expecting a boolean to be returned back.
So this means that we are we were not able to successfully continue user activity from Siri and now
we have an intent property assuming that it comes in from the user activity which is created using this
intent.
Because remember the user activity is set and if it is successful it's passed in through our completion
handler.
So let's go ahead and down below here.
Now that we have our intent we're going to go ahead and basically print that it was successful app delegate
start work out it is true then we're going to just go ahead and print out the intent and we'll see what
we get.
Then at the end we return true because it was successful.
Very cool.
So now we are able to continue our user activity but we have not yet connected our app and the Siri
related stuff.
We have our intent here and with that.
Check it out.
If I if I type intent dot I can get the gold value which is the amount of time I asked I could get the
work out.
Name you know run or walk or cycle or whatever.
I can pull out all that information but we have not yet set up a way for our workout books to access
that and to get that.
So let's go ahead though we have our intent here.
We have our app delegate set up to continue that information.
Let's go ahead and let's test it.
Let's see what we actually get.
So let's select our leg day scheme let's build it to iPhone 8 and let's see how it works we're going
to just give it a test and we'll say you know start a workout in this app.
Ok cool.
So start a walking workout.
I don't know let's see how it works.
Leg day.
Ok cool.
So that's that's where we set up in our intent handler here.
That was good.
We said start a walk work out and the cool thing you can say walking or walking it understands that
you mean walk.
Now we handled it in the app and we passed the user activity so watch what happens if I open leg day.
Look what we get.
We get a print out here.
Start work out intent is true.
And we have all this information the workout name is walk.
We don't have a location type or a goal unit type.
And the goal value is null.
Now that's because we didn't set a time.
Now check it out if I said start a five minute walking workout.
Leg day
if I open it it says Go value 300 because five minutes is the same thing as 300 seconds.
Wow that's really really cool.
Let's try.
Let's try saying a phrase that it doesn't know.
Start a workout.
Cool call leg day couldn't find a match and work out if we open it up it's going to say no and no it
could not successfully find a workout.
Let's try it again.
Let's just let's try one that is a workout but is not accepted because we can find it to walk or run
start a 23 minute run cycle workout
cycle
started 23 minute cycle workout.
OK.
So even though it is a successful workout that we can actually use it just printed out cycle.
We can't actually use it in our app because we have locked it down to only accepting walk or run.
WOW GUYS IT'S WORKING.
That's really really cool.
So we are handling our intent which is to start a workout or run or or walk.
And so guys this is really cool our app delegate here is creating an instance of user activity and it's
passing it in to our intent that is seriously the coolest stuff.
So yeah guys this is amazing.
We can now successfully handle intense for starting a workout using Syrie kit and use our app delegate
to continue that activity in our application.
So very cool stuff in the next video we're going to actually configure these results the ones that printed
out here the goal value as well as the workout name using a data service we're going to create a singleton.
And this is actually the recommended method by Apple is to create a singleton and then use your intent
handler to pass the intent to your app delegate and then use your app delegate to set an instance of
and start work out intent.
And then you can use that singleton class to access all that data from your workout.
VC OK so we're going to use a singleton class to manage the data that's being passed around so we have
one static instance of data that's available to us throughout the entire lifecycle of the application.
So let's head over to the next video and let's configure those results using a data service.
I'll see you there.