WWDC2017 Session 214

Transcript

[ Applause ]
>> Welcome.
Good afternoon everyone.
I'm Sirisha from SiriKit
Engineering.
I'm joined by my colleague and
friend Tin to talk about all the
cool new features we are
bringing this year in SiriKit.
SiriKit was introduced last
year, a brand new way for
everyone to do things in their
apps using their voice.
The main goal of the release was
to make sure to give you the
ability so your services and
content can be integrated with
our SiriKit so users can now
talk to their apps using Siri.
To make this happen, we've
opened up numerous domains like
Workouts, Messages, Ride
Booking, just to name a few.
Every domain had one or more
intents.
And intents had a specific task
like the Messaging domain.
Users were able to send a
message or search a message.
Ride Booking, everybody were
able to book ride in their
preferred apps.
Or paying bills in Payments
domain.
Because of these intents, we
gave you the ability to pick and
choose the intents that you want
to register that best suited
your app capabilities.
In our release Watch 3.2 we
started supporting SiriKit on
watchOS platform.
By writing a Watch extension you
were able to take all the
advantages of SiriKit Intent
framework on the Watch.
As our ongoing effort to make
your experience seamless and
easy, we've added our support to
simulator.
Starting iOS 10.3 and watchOS
3.2, you were able to debug and
test while writing SiriKit
extension.
This is a big year for us.
Great reception and amazing
feedback made this happen.
Let's take a sneak peek about
all the cool things we are
bringing this year.
A lot of new domains and many
more intents.
Brand new APIs to give you move
control to customize the feel
and look at your apps view in
Siri.
And lots of enhancements to our
systems and APIs for a much
improved user experience.
So, let's talk through the
domains first.
We've added new intents to our
Payments domain.
We've add our support to Lists
and Notes functionality.
If your app uses visual codes,
you can start integrating with
SiriKit starting this fall.
Payments was introduced in iOS
10.
When we introduced, we added our
support to sending money and
requesting money.
In our 10.3 release we've added
the support for bills.
Users were able to search for
bills and pay bills.
We are extending our support
further this year by adding our
support for accounts.
Users will now be able to
transfer money from one account
to another, or search for
account information.
Let's take a look at these.
First I'm going to talk about
the transfer intent.
If you look at the screen, Siri
is very capable and powerful to
understand such long requests.
For right now I'm just going to
walk through line by line.
Transfer $10 tomorrow.
$10 will be mapped as amount.
And tomorrow is converted to the
exact date.
Easy. The transaction properties
are simple and map rightly.
What about accounts?
Accounts can be referred in many
ways.
I sometimes like to use it just
by organization name.
Or, like an account type like
I've used here: checking,
savings, credit.
Siri understands all times of
accounts and makes sure that it
infers rightly and then gives it
to your app.
Well and good.
What is this Rainbow Savings?
This is the name I have used
when registering my account in
one of my apps.
And I want to make sure that
Siri understands my account
nicknames, too.
And how is this possible?
When you registered
user-specific data using our IN
Vocabulary API, we will be able
to understand user's specific
information.
You can look for more
information of IN Vocabulary API
in this link.
So, let's talk about Search.
Our second intent is a Search
for Accounts intent, which will
be able to list all the account
types if the user just asks to
list all the accounts.
Just enough information to
distinguish between the
accounts, along with the
balance.
And if the user wants to know
more about each account, they
can just click on any of the
item to get a detailed view.
Search for Accounts intent, not
just shows all the accounts, but
also can be used to query for
specific account information.
Like here.
What is the balance on my
Rainbow Checking account?
I'm asking specifically my
balance on a specific account.
And Siri perfectly understands
it and then gives the user the
required information.
We don't only support the normal
balance, but also we've added a
couple of balance types.
Like if your app supports
airline mileages or reward
points.
Siri can understand them as
well.
How many miles do I have on my
Sparkle card?
Siri understands it and then
passes it to your app.
And thus giving the user the
required information.
So, INTransferMoneyIntent can be
used to transfer money from one
account to another.
INSearchForAccountsIntent can be
used to check balances, to list
all the accounts or to check any
specific account information.
That's all we have for Payments
this year.
With our analysis, we found out
that managing lists and notes is
one of the very popular use
cases in Siri users.
And so, this year we're
extending our support to support
lists and notes.
We've added all the APIs to make
sure that users can create,
edit, manage, their lists,
notes, and reminders.
Not just that, but also users
will be able to search in their
lists and notes.
Let's take a look at them.
This is an example to create a
list.
I can ask Siri to create a list
by giving a title and also the
contents.
And Siri is powerful enough to
distinguish between them,
understand them, and pass on the
right information, filling in
the intent, giving it to you to
create the view.
This is one of my favorite
intents: the joys of marking
tasks done.
SetTaskAttributeIntent can be
used for this.
This has a task type, which is
completed, not completed.
And that carries the information
between Siri and the app to make
sure that we do the action
correctly.
We've added brand new intent to
support reminders.
We can create reminders in many
ways.
Siri supports two types of
reminders: spatial and temporal.
Let's talk about spatial first.
An example here: Remind me to
leave work at 5 p.m. in
UnicornNote.
I'm asking Siri to remind me to
print slide when I get to work.
I'm making -- I want Siri to
make sure that it understands
the geolocation of the word and
then pass on the information to
you so you can create the right
reminder for the geolocation.
The next example: Remind me to
leave work at 5 p.m. This is to
make sure that the date trigger
is created.
If you look at both the
examples, Siri is powerful
enough to understand when I said
"leave work at 5 p.m."
to create a date reminder, but
not a location reminder for
leaving work.
And in the before example, Siri
created a location trigger when
I said "arrive at work."
Siri is very powerful in parsing
these use cases and
understanding them to create the
right intent and pass it over to
you.
So, CreateTaskIntent can be used
to create tasks, lists.
AddTasksIntent for the reminders
and adding tasks to the existing
ones.
SetTaskAttributeIntent to set a
task or to mark it completed or
to update it to a reminder.
Let's talk about the notes.
Notes can be created in many
ways.
I can create by using the title,
the content and even under a
folder.
And Siri supports all these
options.
So when I ask Siri to create a
note with just given title, it
just creates a blank note.
I can also ask Siri to create a
note under a specific folder
along with its content.
Siri parses the whole user
intent and then maps the
appropriate title, group name,
and content into the intent and
then pass it over to you to
create the right note.
And adding to an existing note.
This is possible with Siri, too.
Here, Siri understands the
target note as WWDC.
And then the actual content.
And then passes the information
over to you to create the note.
Let's take a look at the
intents.
CreateNoteIntent to create brand
new notes.
AppendToNoteIntent to add to an
existing one.
The next big intent in the Lists
and Notes is Search.
When you get asked to just show
all the information, Siri
understands and then passes the
intent to your app.
And Siri lists all the notes,
lists, reminder, passed on by
the app to us.
We can display as is if you want
us to.
Or, you also have the option of
mentioning it to be sorted by
date, where Siri will go ahead
and sort all the items by date.
And then show it to the user.
Not just showing all the items,
but user can also query using a
specific type, like show just
the notes or just the lists.
Or show the notes I created
yesterday.
Or even show my completed tasks.
There are many types we support
under this intent.
And the intent itself is called
SearchForNotebookItemIntent.
And it supports all these types.
So user can ask if using any one
of these and Siri will
understand perfectly and thus
completing the action.
And that's all the Notes and
Lists new APIs we have.
Visual codes like QR codes, Bar
Codes, are becoming very popular
these days.
They're being used in numerous
ways in the apps.
Like they're used to just open a
web page instead of typing a
tedious URL, especially they're
in foreign languages.
Just showing a QR code opens a
web page.
Or using them to send payment or
request payment just by showing
a code.
Paying at a gas station or
paying to friends.
Apps are using bar codes to
perform specific tasks.
And not just bar codes or QR
codes.
We are also having codes as
contacts in networking apps to
connect to each other instead of
going finding a person and then
connecting.
By just showing a contact code,
we are able to connect easily.
And starting iOS 11 Siri will be
supporting visual codes.
Users will now be able to say
"Show my UnicornChat code,"
which means Siri understands
that this is a visual code
intent, and then pass on the
information to your app.
Whereas if the code could -- we
support different types of
codes, depending upon what app
gives us, we share it back to
the user.
And the intent that can be used
to this functionality is
INGetVisualCodeIntent.
It has one property type,
visualCodeType, which supports
-- it could be a contact or a
request payment or send payment.
By registering to this intent
users will be able to ask Siri
to show the visual codes of any
of these types in their favorite
apps.
Now I invite my colleague and
friend Tin over to show you this
in action.
[ Applause ]
>> Thank you Sirisha.
Hi everybody.
My name is Tim.
And I'm engineer on the Siri
Client Team.
So last year at WWDC we
introduced an app called
UnicornChat.
It was great.
Let our unicorn friends, like
Celestra here, send messages to
Sparkle Sparkly.
And it was great.
This year we want to add the
brand new Visual Code Intent
support to the app.
And it's super simple.
So the first thing we want to do
is we want to make sure to
modify our info.plist.
If your app hasn't yet adopted
SiriKit, all you need to do is
to go and create in it
IntentsExtensionTarget in your
project, and you'll have the
info.plist, which you can edit.
Once you have it, go ahead and
add under the Intents Support
Key the new visuaCodeIntent.
The next thing that's important
to notice is your principal
class.
The principal class is where
Siri will call into your app and
ask you to begin handling your
intent.
And that's where we're going to
begin modifying our application.
I'm also going to modify the
intents extension scheme and
fill out this field Siri Intent
Query.
I can prepopulate it with text
to show my UnicornChat code.
This way every single time I
build and run, Siri will
prepopulate that text.
I don't need to speak to it
every single time.
This will make debugging and
development much faster.
Let's code now.
Thank you.
[ Applause ]
Let's take a look at the demo.
So here I am in my principal
class of my intents extension
for UnicornChat.
And we're already hailing the
SendMessageIntent.
So let's go ahead now and handle
that VisualCodeIntent.
It's pretty easy.
If you're handling multiple
intents within your application,
it's a great idea to split them
up across multiple classes.
This separates your logic and
makes things easier to test and
debug.
So let's go now into our
VisualCodeIntentHandler class.
As a reminder, you need to do
three things when you're
handling a SiriKit intent.
The first thing you want to do
is to resolve your intent.
Resolving gives you an
opportunity to customize Siri's
properties and how it handles
the properties of the intent.
Second, is Confirm.
Confirm gives you the place to
tell Siri a ready signal, that
you're ready to handle the
intent, as well as do
validation.
Finally, you'll just go ahead
and handle your intent.
For this VisualCodeIntent, we'll
return an image and tell Siri to
display it.
So let's go ahead and get
started.
I'll make my class conform to
the INGetVisualCodeIntent
handling protocol.
And the compiler's telling me I
need to implement some required
methods.
Go ahead and do that.
So the only required method is
the Handle method.
But we strongly recommend you
implement both Resolve and
Confirm.
This is going to give you the
most control and customization
over your user's behavior within
Siri.
I'm going to move this out of
the way for now.
And we'll implement Resolve
first.
Again, resolution is where you
customize your behavior for
Siri's properties of the intent.
For the VisualCodeIntent,
there's only one property, and
that's the VisualCodeType.
As Sirisha mentioned, it could
be a contact code, a payment
request code, payment send code.
So let's implement our custom
logic now.
Here, if the user asks for a
contact code, we'll tell Siri
we're going to handle it
successfully as a contact code
type.
If the user doesn't specify
which kind of code they want,
like they say "Show my code"
using UnicornChat, Siri will
populate the type as unknown.
And here we can customize the
behavior and also tell Siri we
want to handle that as a contact
code type.
We won't support Payment Send or
Payment Request in our demo app.
So we'll tell Siri it's
unsupported.
And when we do so, if the user
asks for a payment code, Siri
will intelligently dial out to
the user in all the languages
that Siri supports.
We don't have to write a single
line.
So that's the power of SiriKit.
Now we're done resolving the
properties.
Let's go ahead and confirm this.
So confirmation, again, is where
we give Siri that ready signal.
And it's a great place to do
validation.
So we want to make sure that our
Unicorn user has a valid and
active account before we show
that contact code.
If they do, we'll go ahead and
return Ready response code to
Siri.
But what happens if the user
doesn't have a valid account?
Well, it'd be great to launch
our app and be able to perhaps
ask them to sign up or
reactivate their account.
And we can do that using a
custom user activity.
So we'll create a custom user
activity with a custom user info
dictionary with our error
specified.
And we'll turn to Siri
failureRequiringAppLaunch and
pass the user activity.
Now, if the user asks for a code
and they haven't signed up or
their account's inactive, Siri
will show an error and give the
user an opportunity to launch
the app.
And if they launch the app, the
user activity is passed on to
the app.
And then you can extract that
information, ask them to sign
up.
Make sure they can connect with
their Unicorn friends.
So now we're done with Confirm.
Let's go and handle this.
Handle's very straightforward.
We're just going to return a
success code to Siri in the
response.
And we'll set the visual code
image property on that response
to be our contact code image.
So this looks pretty good.
Let's build and run now.
It's prepopulated my request.
And there we have it.
Our brand new visual code.
Looks great.
[ Applause ]
So let's switch back now to
slides and recap.
So when supporting intents, all
you need to do is remember to
modify your info.plist.
Again, if you don't have an
info.plist, just go ahead and
create a new Intents Extension
Target in your app and you can
edit it.
Next, make sure to modify your
principal class, handle that
intent.
Finally, Resolve, Confirm and
Handle your intent.
Super simple.
All right.
I'd like to switch gears a
little bit and talk about
customizing your UI within Siri.
As a reminder, there's two types
of extensions in Siri.
The first type is the Intents
Extension, which you just saw.
It's where you do your Resolve,
Confirm, Handle, handle your
business logic.
This is required.
The second type is an Intent UI
extension where you can use to
configure your view.
And this is what we're going to
be talking about now.
So, in iOS 10, we let you
customize parts of your view.
Here's a RequestWriteIntent.
And we allowed you to customize
certain parts of the view like
replacing the map with your own
custom view here.
We really like unicorns here.
So, this was great.
It lets you show additional
information, your own style.
But we noticed sometimes there
are issues.
There's duplicate information,
like this pickup location, drop
off location are duplicated.
Same with the fare.
This is because you didn't have
full control over all the visual
elements within Siri.
Well, this year in iOS 11 we're
going to give you that full
control.
And in order to do that, I'm
going to explain it to you a
little bit how Siri draws its
views.
Siri represents its views as a
stacked series of UI elements,
each of which is backed by data
called a parameter.
So for example, the map is
backed by a pickup location
parameter, so on and so forth
for the rest of their views.
The ride option name, drop off
location and so on.
Here's another example.
Here Sparkle Sparkly is coming
to pick us up in a majestic
unicorn.
And he's represented by -- this
view is represented by two
parameters, a ride driver and a
ride vehicle parameter.
So some views can be represented
by multiple parameters or sets
of parameters.
In iOS 11 we expose this as a
new class called INParameter.
And this is a class representing
that data.
So here's the pickup location
INParameter.
It's constructed using a
parameter class.
In this case the
RequestRideIntent.
And then a key path which is a
property -- a location to a
property on that class.
So the parameter represents a
sort of key to the value.
And we want to be able to get
the actual value, too.
So there's a new method also on
the INInteraction called
parameterValue.
When you pass the parameter into
the interaction, you'll get back
the actual value.
For the pickup location, it
would be a CL placemark object.
Different parameters will have
different parameter value types.
For example, the price range
parameter would have an
INPriceRange type.
So, with this concept of
parameters, we can go from
giving you control over a single
view to all of the views,
customizing them for parameters.
And we'll walk through that now.
This is the principal class of
the intents UI extension.
It conforms to
INUIHostedViewControlling.
This is the same as before.
And our new method is called
configureViewFor parameters.
So you'll be asked to configure
your view for a set of
parameters.
You'll be given an interaction
object.
This will let you resolve those
parameter values.
You'll be given a context.
This will tell you whether
you're being drawn within maps
or within Siri.
And then finally, you'll be
given a completion block.
And you'll call this and it has
three parameters.
The first is a Boolean.
You'll return True or False
here.
True meaning you wish to draw a
custom view for this set of
parameters.
False means you want to let Siri
draw its default view.
Second is the set of parameters
that you're handling if you
choose to return True.
Finally, you return a size for
your view for Siri to draw.
Let's walk through a concrete
example and show you how we can
customize a Request Ride
Interaction using parameters.
We'll make more unicorns.
So, on top is Siri.
Bottom is your Intents
UIExtension.
You're first going to get called
with an empty set of parameters.
This will give you a chance to
draw additional information,
handle parameters up front, and
for this case in our example,
will return False.
Meaning we want to let Siri draw
the default view for this
parameter.
And the default view for an
empty set of parameters is
actually no view.
This is how it looks like in
code.
Now, Siri needs to keep calling
configureView until it resolves
all the parameters for the
interaction.
So the next view -- or the next
set of parameters is the pickup
location.
So it's going to ask you to
configure your view for this
section.
This time we're going to turn
True.
We're going to tell Siri we're
going to handle that pickup
location.
And then the size for our custom
view.
When we do this, Siri will
replace its default view with
our custom view.
And it will remove all instances
of the default view it would
have drawn.
Finally, it will respect the
size that we asked for.
So here's how it looks like in
code.
We'll go ahead and define our
pickup location parameter.
We configure our view when we're
asked to configure for the
pickup location.
And tell Siri True, and we're
handling it.
And finally we'll move our False
completion to an else block.
So Siri, again, is going to keep
calling configureView until it
resolves all the parameters.
Then next is the ride option
name.
And not only can you tell Siri
False, to let it draw a default
view, or configure one parameter
at a time, you can actually tell
Siri you want to configure
multiple parameters at a time.
Or all the rest of the
parameters.
So here we're going to tell Siri
we're going to handle the ride
option name and then all the
rest of the parameters in the
view.
And Siri will place all those
parameters with our custom view.
And Siri will no longer ask us
to configure the view any
further because we've told it
we're handling the parameters.
Here's how it looks like in
code.
We configure our parameters.
We've commented this part out.
Pick up location's just like
before.
Here we're handling the ride
option name and all the rest of
the parameters.
And then our completion, False.
So we go from this view, which
has duplicate methods to be able
to control all of the views and
all the parameters for those
views.
And not only can we do this type
of layout, we can do any type of
custom layout we want.
We can draw some custom views.
We can have Siri draw the rest.
You can draw all custom views.
Have a custom header.
So, it's super powerful.
So let's take a look at this
live in Xcode.
Customize our Unicorn Ride app.
We're going to use a pink theme.
Unicorns love pink.
And we're going to handle two
views.
We're going to handle the fare
and special pricing parameters
on the top view.
And then pickup location, drop
off location, ride option name
on the bottom.
And again, I'll use the Siri
Intent Query feature to
prepopulate a request.
So let's take a look at a demo
again.
So here I am in my principal
class for my Intents UI
Extension.
It conforms to the
INUIHostedViewControlling
protocol.
And let's go ahead and implement
that new configureView method.
The first time around, I'll
return False to every single
thing.
So Siri is going to draw its
default views for all the
parameters.
We can also put brake points
here during debugging to see
which sets of parameters we're
getting called for in which
order for the interaction as
well.
Let's build and run this.
All right.
We've got our default view here
because we've told Siri False to
all the parameters.
This isn't very Unicorny, so
let's get started and make it
more pink.
Let's take care of that fare and
special pricing parameters.
So back in our controller.
We'll define parameters that
we're handling, fare and special
pricing.
We'll handle our parameters and
then extract the real values for
these parameters from the
interaction object on that first
call when Siri asks us to
configure for an empty set of
parameters.
Next, we'll take our parameter
values, go ahead and use it to
configure our Unicorn Ride View.
And then we'll tell Siri we're
handling the custom view for
these parameters, and then the
size.
Go ahead and move this to an
else block.
Let's build it around this.
And it's looking a lot better.
We got our pink view here
handling the fare and special
pricing.
And because we've returned False
to the rest of the parameters,
Siri's drawing the default views
for pickup location, drop off
location, ride option name.
So to fully customize our view,
let's go ahead and take care of
the rest of the parameters.
Here we're just defining the
rest of our parameters, just
like before.
Once again, we're configuring
our view.
When Siri asks for the pickup
location, extracting the real
values using the parameterValue
method for the interaction.
Finally we'll use those values,
again, configure our Unicorn
Ride View for these last
parameters and tell Siri we're
handling them with our custom
size.
This looks pretty good.
So let's build and run this one
now.
And now we've got our fully
Unicorny custom ride view.
So that looks great.
[ Applause ]
Let's go back to the slides.
Just to recap, when configuring
your view for parameters, know
that you'll be called multiple
times to configure your view.
You're first going to be called
with an empty set of parameters.
So again, you can draw
additional info, your own custom
header.
Or you can even handle
parameters up front here.
You'll be called in order for a
set of parameters for a given
interaction.
You'll be able to find the set
of parameters in the order in an
upcoming update to the
documentation.
Finally, just go ahead and
handle your parameters, return
the size up to Siri and draw
your view.
In an upcoming seed we're going
to add a parameter to the
configureView method called
Interactive Behavior.
So certain views and certain
parameters have interactivity
associated with them.
So for example, the map, you can
tap it, you'll get another view.
That's like a next view.
Certain views may launch your
app.
So the Interactive Behavior
parameter will give you hints
about the type of interaction
that's available for these
parameters.
And you can use that to
customize your view as well.
There will also be another
method called Description of
Interface Parameters on your
Intents UIExtension Context,
which you can use during
debugging in order to printout
the order of parameters and the
set of parameters during a give
interaction.
So, this is the brand new
INInteraction API.
It's super powerful.
And we can't wait to see what
you guys build with it.
I'm going to hand it back to
Sirisha to talk about some
additional enhancements.
Thank you.
[ Applause ]
>> Thank you, Tin.
Along with adding more domains
and the powerful parameters Tin
just introduced, we've spent a
lot of time enhancing our
systems and APIs.
I'm not going to go over all of
them, but I want to talk about
two of them.
First, I'll cover Background
Workout App Intent Handling, an
ability to start workout apps in
background.
And Alternative App Names.
We'll get to it in a minute.
Workouts are very popular
intents.
Users love to use Siri to
control their workouts.
It's very easy.
The current implementation when
user requests any action on a
workout, Siri calls the
extension.
And then the extension hands it
over to the app.
And thus Siri asking permission
for the user if the device is
locked before launching the app.
We changed this a bit this year.
We wanted to make sure that
before launching the app we
launched the app instead of in
the foreground, but in the
background.
So users can now just talk to
Siri and have the app launched.
And this is for the Workout
Intents starting iOS 11.
Let's look in the code.
This is the current
implementation.
A sample code for a start
workout intent response.
The extension usually returns
continuing app, which when Siri
calls the application method in
the UI application delegate,
passing the NS userActivity,
prompting an app launch.
We've added two new things to
change the flow.
We have added a new intent
response code Handle an App.
So, you have a choice to return
Handle an App response code to
make sure that we call a new
application method.
We've added a new application
method on the UI Application
Delegate.
This takes IN Intent and a
completion handler.
So, when you pass in Handle an
App as an intent response code,
and implement the new
application method, we will call
the new application method,
prompting to launch the app in
the background.
This is very useful when the
users just want to start Workout
or pause, even through airports.
They don't even have to touch
the device.
Let's take a quick look at the
flow.
How does this look?
User wants to start a workout.
We launch the extension, call
the handle method.
And the extension returns the
new intent response code, Handle
an App.
And then Siri calls the
application, the new application
method, passing the IN Intent
and the completion handler.
And that completion block
inserts the intent response
code.
And then application will be
launched in the background and
passing the success back to Siri
with the completion of the
activity.
We believe this will make user's
experience more easy, more
seamless while controlling their
workouts.
And we're very excited for this.
The second enhancement I'm going
to talk about today is
alternative app names.
Usually user can actually call
an app in different names,
different varieties.
Like UnicornPay can be just
called as Unicorn.
UnicornPay or CornPay.
We want to make sure that we
understand all the variations of
the app names the user uses and
invoke the right app.
So, to make this happen, we've
introduced a new field
AlternativeAppName in the
.plist.
While registering in the .plist
you have the ability to fill in
all the app names that you think
a user might use to refer to
your app.
There is a field called
AlternativeAppNames which takes
the actual names and then the
pronunciation hint you can also
fill in, if you think that's
necessary.
This will help Siri understand
all the variation of the app
names and make sure to invoke
and call the right app the user
is expecting.
So far we've introduced new
domains, Lists and Notes, and
visual codes.
And new intents in our Payments
domain to support accounts.
Brand new APIs to give you more
control to customize the views.
My colleague Tin introduced
this.
And finally, the enhancements
like starting a workout app in
the background and also giving
you the ability to provide us
all the alternative app names
that you think a user can call.
Please visit our website
developer.apple.com for more
information under our session
214.
We have another session coming
up, Making Great SiriKit
Experiences, where our experts
will talk about methodologies,
techniques, helpful hints you
can use while you're writing in
Siri Extension.
Thank you all for joining us
today.
We're very excited to see all
the new things you're going to
bring using our new APIs.
Thank you.
[ Applause ]