Transcript
[ Music ]
[ Applause ]
>> Good afternoon.
And welcome to Integrating with
Siri Event Suggestions.
My name is Sofiane, and I'm an
Engineer, working on Siri
frameworks here at Apple.
And today, I'll be joined by my
colleague, Magnus.
We're really thrilled to be here
today to tell you all about how
to integrate your apps with Siri
Event Suggestions.
Siri is the virtual assistant we
all know and love, and with
SiriKit, your app can work with
Siri, for things like sending
messages, requesting rides, as
well as expose the key
capabilities of your app using
shortcuts.
Siri is also deeply integrated
across our platforms, adding
on-device intelligence to the
apps you use every day.
In Calendar, Siri is personal
and knows about your
reservations to help you get
organized, and Siri can then use
that information about your
reservations to make proactive
suggestions throughout the
system.
So, on the lock screen, Siri
notifies you when it's time to
leave, based on traffic
conditions.
And when you open Maps, you get
Siri suggestions, which make it
super convenient to get
directions right to your
destination with just one tap.
Now, when you get there, Siri
can proactively suggest to turn
on Do Not Disturb and help you
stay focused on what matters.
And all of that starts with the
system knowing about your
reservations, wherever they come
from, whether it's in the car
rental reservation in mail, a
restaurant reservation in
messages, or even when you're
booking a flight directly in
Safari.
Now, in iOS 13, we're really
excited to introduce new APIs
for your apps, to integrate
directly with this ecosystem.
[ Applause ]
So for example, when you view
your flight reservation inside
the American Airline app, the
app donates that information to
the system.
Siri can then use it to
automatically show a
notification and add that flight
to your calendar.
Siri will then go on to make
proactive suggestions for that
flight, at the right time, in
all of the places that I
mentioned before.
And all of that intelligence
happens directly on the device.
But we didn't want to stop here.
This year, we wanted to extend
that deep system integration and
promote your app in even more
places in the system.
So, in iOS 13, if your app
supports check-in, it can get
promoted right on the lock
screen, taking users directly
into your app at the right time.
Also new in iOS 13, with maps,
when the time is right, when a
user goes into maps, they can
get up to date information about
their flight, and even get
directions, indoor directions
directly to their gate.
So Siri is there to help at
every step of the way, from the
moment you make your reservation
to the moment you walk in.
So, by now, I hope you're all
thinking that is pretty cool,
hopefully.
But how does that all work?
Well, the API is built as part
of SiriKit which allow you to do
many things, like setting up
shortcuts, sending payments, and
much more.
And more specifically,
everything we will talk about
today is exposed as part of the
intense framework.
We support reservations across
many categories, ranging from
restaurants to ticketed events,
to various forms of transit, and
this year, we're introducing new
classes in the intense framework
to represent details for all of
these reservation categories.
Now, all of these classes
inherit from the new IN
Reservation Class.
So, for instance, to represent a
restaurant reservation, you can
create an
INRestaurantReservation object.
Those of you familiar with
SiriKit will recognize the
INInteraction API, which is also
used for shortcut donations.
So when a user views a
reservation inside your app,
your app creates an interaction
and donate to the system.
Interactions are made up of an
intent, an intent response,
which together represent a full
user interaction.
Now, this year, we're
introducing the new
INGetReservationDetailsIntent,
an intent response that are
intended to capture details that
pertain to user's reservations.
This provides a way for your app
to share those details with
Siri.
Now, the intent response takes a
list of INReservation objects,
as we just saw previously, which
represent your specific
reservations.
So here, for example, we are
creating an INLodgingReservation
and attaching it to the intent
response to represent the
details of a hotel state.
Now, all that is left for you is
to donate that interaction to
the system, so that Siri can use
it in places like Siri event
suggestions, or Siri shortcuts,
for example.
Okay, now, let's move on and
talk about the three easy steps
that your app should follow to
take advantage of all these
great features.
And first, we will talk about
how to create and donate good
interactions.
Next, we will look into how to
adopt the new reservation
actions API, so your app can
benefit from the new check-in
shortcut feature.
And finally, your app may be
launched with a reservation that
you previously donated.
So we will talk about various
launch scenarios that you should
handle.
And now, I'd like to invite my
colleague, Magnus, up to tell us
all about the API.
Magnus?
[ Cheers and Applause ]
>> Thank you, Sofiane.
Hey, everyone.
My name is Magnus.
I'm excited to be here today to
talk to you about Siri event
suggestions.
First, I'll show you a demo of
how to use the API, and then we
will talk a little bit about the
details later on.
Let's jump into the demo.
So, I'm working on this flight
app called My Flights.
Let's open it, and see what it
looks like.
So it displays a list of all my
flight reservations.
If I tap one, I can see more
details about the reservation.
I want to take advantage of the
Siri event suggestions API, and
donate the reservation details
when it is displayed to the
user.
Let's switch over to Xcode.
Now, my app consists of some
view controllers and a server,
where I get my reservation
details from.
Since I want to donate the
reservation details when they're
displayed to the user, let's
take a look at my
ReservationDetails
ViewController.
The view controller gets the
reservations from the server.
For the purposes of this demo,
the server returns
INReservations SiriKit objects.
I started doing some work on
this already, but there is still
some missing code here, marked
by to-dos.
Let's go to the server, and see
what makes up the INReservation
object.
In my server code, I have a
method called
createFlightReservation, to
create and save the reservation
so I can access it from my view
controller.
I'll create the
INFlightReservation object here.
Now, this method creates an
INFlightReservation object.
This object contains all the
reservation details about the
flight.
Let's take a look at some of the
properties.
First up is the itemReference.
This is a unique identifier for
this reservation item.
It will be used when the system
launches my app to tell it which
specific reservation item to
show.
In my app, the reservationNumber
is unique for this flight.
So I will use that for the
vocabulary identifier.
I also said a spoken phrase that
can be displayed to the user.
I'm using Flight XX815, which is
short, and descriptive.
Here are some common properties
that are shared among all
reservation types.
Like the reservationNumber, and
the name of the
reservationHolder.
We also want to capture
information about the flight.
It's created here in a separate
method called createFlight.
Let's jump to the
implementation.
Here, I'm creating an INFlight
object.
This represents all the details
about the flight, such as the
flight number, the airline,
along with the information about
departure and arrival.
I still have some to-dos here,
so let's go ahead and fix that
starting with the airline and
airport information.
These objects represent the
airline, and information about
the flight departure and
arrival.
In this case, the flight is from
San Francisco to Paris.
Both airlines and airports are
identified using either an IATA
or ICAO code.
For airports, this is also used
to determine the physical
location of the airport.
I'm adding gate and terminal
information for departure, since
it's already known at this time.
I don't know the gate
information for the arrival, so
I set that nil.
Next, I also need to specify the
departure and arrival time for
my flight.
We are using the
INDateComponentsRangeClass to
represent the departure and
arrival time.
For the best user experience,
I'm also setting the local time
zone, sorry, I'm also setting
the local time zone for the
departure and arrival airports.
Okay. So we set all the
information we need to represent
the flight.
Let's go back and look at the
rest of the reservation.
I want to provide my users with
a great check-in experience, so
I want to take advantage of the
new check-in shortcut.
To do that, I need to create a
check-in action.
Let's jump to my
createCheckInAction method.
This method creates an
INReservation action, which
consists of a type, a valid
duration, and a user activity.
In my case, the type is
Check-In, and the valid duration
is the time when the user can
check-in online.
During this time, the user
activity I specify will be
displayed as a suggested
shortcut.
I'll start by creating the
NSUserActivity.
I'm creating the NSUserActivity
with an activityType that lets
my app know that this is a
check-in activity when it is
launched.
I set the title to Check-In for
Flight XX815.
This is displayed to the user in
the shortcut, so make sure it's
short and descriptive.
Next, I'm adding the details I
need to know to start the
check-in process when my app is
launched.
I add them to both the user info
under requiredUserInfoKeys
properties.
I also add a webpage URL value.
So the check-in process can be
used even if my app is not
installed.
So I'm pretty happy with this
user activity, but I also need
to specify the valid duration.
We're using EndDateComponents
range again here.
This time, to represent a start
and end time for the valid
duration.
In this case check-in starts 24
hours before departure, and ends
one hour before departure, so
that will be my valid duration.
That's really all we need to
create the great check-in
shortcut.
Let's go back and summarize what
the reservation we created.
Now, we have all the information
we need including the
reservation details, the flight
information, and the check-in
action.
Let's go back to the
ReservationDetails
ViewController, to add the
donation code.
So, our view controller already
knows about the reservation we
just created.
I set up a method here to donate
the reservation.
So let's add the donation code.
Let me just remove the
navigator, so you can see
better.
So I'm starting by creating the
intent.
The intent tells Siri which
reservation was displayed to the
user.
It takes two parameters, the
ContainerReference, and the
ItemReference.
The ContainerReference uniquely
identifies the reservation as a
whole.
In this case, I only have a
single reservation item, the
flight.
So I will use the ItemReference
I set on the ReservationItem, as
the ContainerReference.
If I have multiple
ReservationItems, such as a
hotel and a flight, I would
create a new ContainerReference
to represent that reservation as
a whole.
I'll set the
ReservationItemReference as
property to nil.
This is populated by the system
when launching my app.
In addition to the Intent, I
also specify an intentResponse,
and add my reservation to it.
This informs Siri about what
reservation details I display to
the user.
Finally, I'll add the intent and
intentResponse to an
INInteraction, and donate that
to the system.
So, now we've written all the
code we need to donate this
reservation, but there is one
more thing we need to check
before we can launch the app.
I need to add
INGetReservationDetailsIntent,
and my custom CheckInActivity to
the list of supported activity
types in my info.plist.
Luckily, I already did this
earlier, so we're good to go.
First, let's recap.
We created and donated an
INFlightReservation that
contains all the information
about the reservation.
Now, Siri knows about the
reservation, and can provide
proactive suggestions throughout
the system.
We also added an INReservation
action, to provide a great
check-in experience, with a
shortcut that is displayed to
the user, and takes them
directly into the check-in flow
at the right time.
Let's see this in action.
So, I'm back in my app.
Let's view the flight to Paris
reservation like we did before.
When I view the reservation this
time, I see a notification
telling me Siri found an event
and put it in my calendar.
[ Applause ]
Thank you.
[ Applause ]
I'll tap the notification and
see what it looks like.
So, as we can see, Siri used the
information I donated to create
an event in My Siri Suggestions
Calendar.
Now, there is also a link back
to my app.
When I tap it, I am brought
right back into my app.
So that's great.
However, I don't see the
reservation details about the
event that I was viewing in
Calendar, and I think we can do
better.
Let's go back to Xcode and see
how to implement app launch.
To handle app launch, I'm going
to go to my AppDelegate.
When Siri launches my app, it's
going to be launched using an
NSUserActivity.
So I need to implement the
application
ContinueUserActivity, Delegate
Method.
I'm adding support for two
activity types here.
The first is the
INGetReservationDetailsIntent.
This activity type indicates
that a user wanted to see
details about a specific
reservation in my app.
I'll call my
handleShowReservation method,
which will display the relevant
reservation to the user.
The second one is the activity
type I define for the check-in
shortcut.
This is used when the user taps
the check-in shortcut on the
lock screen or in search.
I'll call my handleCheckIn
method when this happens, to
start the check-in process.
So, now handling both cases,
let's launch the app and see
this in action.
First, let's go back to
Calendar, and tap the show in My
Flights button again.
As you can see, my app now
launches directly into the
reservation details for this
event.
Now, this is a much better user
experience.
[ Applause ]
I also added support for the
check-in shortcut, and my flight
leaves tomorrow at 2:50 PM, so
check-in should already be open.
Let's see how that works.
Now, the check-in shortcut
appears both on the lock screen
and in the Search UI.
When I tap it, I'm launched
directly into the check-in flow
of my app.
That's pretty awesome.
[ Applause ]
So let's recap.
We created and donated a
reservation.
We provided a check-in action,
and we made sure to handle app
launch.
This is how we see it, is to
take advantage of the Siri Event
Suggestions API, to provide deep
system integration and the great
user experience.
Now, I would like to tell you
more about the API.
We'll begin with Donations, and
talk about how Siri used the
information you donate in places
like Shortcut Suggestions, and
Calendar.
As we saw in the demo, your app
is front and center in the
check-in shortcut.
We display your app name and
icon along with the information
about the reservation.
Again, we use the title you set
on the NSUserActivity in the
shortcut.
So, make sure you use a string
that is accurate and
descriptive.
Now, Siri automatically
synchronized the reservation
details across the user's
devices using end-to-end
encryption.
So the user might see the
check-in shortcut on the device
where your app is not installed.
In this case, an iPad.
When this happens, we'll use the
web page URL property you set on
the NSUserActivity to provide a
web base check-in flow using
Safari.
So that is a check-in shortcut.
Let's take a look at Calendar.
Now, first up is the Title.
The title is auto-generated by
Siri using the reservation
details you provided.
As you can see, Siri adds a
localized reservation type to
the title.
Depending on the reservation
type, different parts of the
information may be used to
generate the title.
So make sure you provide all
details as is, and do not
prepend or append anything for display
purposes.
Next is Location.
Location is a key component to
the user experience, and it
drives system integrations such
as a time-to-leave notification
and Maps integration.
For most reservation types,
SiriKit uses the CLPlacemark
class to represent locations.
You can create the CLPlacemark
object yourself, or if your app
uses MapKit, you can get it off
the MapKit item.
If you do create a CLPlacemark
object yourself, be sure to
include both location and postal
address if you have both.
If you do not know the
coordinates, set them to 00.
This will let Siri know to use
only the postal address.
Next step is the start and end
time of the reservation.
As you can see, the event
displays both the start and end
time using the user's current
time zone, and the time zone of
the reservation.
So, make sure you set the local
time zone for the reservation or
use UTC if you don't have that
available in your app.
Some reservation types have a
clear start and end time.
For instance, for a flight, use
the scheduled departure and the
scheduled arrival time.
For reservations like lodging
and car rental, use the check-in
and check-out time.
If your reservation doesn't have
a specific end time, set at nil,
that way Siri will use the
de-filterization based on the
reservation type.
Next is the Notes section.
Siri uses the Notes section to
populate it with more
information from your
reservation details that might
be useful to the user, such as
the reservation number or
seating information.
Be sure you populate all the
reservation details for which
you have information, as it may
be displayed to the user.
Finally, Siri provides a link
directly from Calendar into your
app.
Tapping on it launches your app,
so it can display more details
about the reservation.
So, let's take a look at what
you need to know to handle this
in your app.
To understand app launch, let's
take a step back and look at
what we're donating.
Earlier in the demo, we donated
a single reservation item.
But let's consider a case when
there are multiple reservation
items.
For instance, a round trip
flight.
In that case, we have two
reservation items that might
share the same reservation
number.
As such, the reservation number
can be used to uniquely identify
a specific reservation item.
For this reason, your app must
always provide an additional
identifier called the
itemReference.
The itemReference must be unique
for every reservation item in
your app.
How you structure the
itemReference is really up to
you, as long as you're able to
reason about which reservation
it belongs to later on.
In this example, we're creating
a reservation item by combining
the shared reservation number
and the specific flight number.
Next, we add the two reservation
items to an
INGetReservationDetailsIntent
response, and to complete our
donation, we also need to create
the
INGetReservationDetailsIntent.
When creating the intent, we
need to tell Siri which
reservation the user was
viewing.
This is represented by the
ContainerReference.
In this example, we're donating
two flights that are part of the
same reservation.
So we are setting the
ContainerReference to the shared
reservation number, since it
uniquely identifies the
reservation as a whole.
Finally, we are setting the
Reservation Item References area
to nil.
This is only used when launching
your app, to let it know which
specific reservation the user
wants to see.
So that's our donation.
Let's take a look at how this
information is used when
launching your app.
When your app is launched to
show reservation details, it
will be launched using an
INGetReservationDetailsIntent.
This represents what reservation
the user wants to see details
about.
In this example, we're launching
the app with an intent saying
the user wants detail about a
reservation identified as B9C8.
If the reservation item
reference array is set to nil,
your app should show a UI
displaying this reservation as a
whole.
In our previous example, that
would mean showing both flights.
The user might also want to see
details about a specific
reservation, such as one of the
flights from our previous
example.
In that case, your app will be
launched with a Reservation Item
References Array populated with
a single item.
This will be the item reference
you set on the INReservation
object for this reservation.
In that case, your app should
show a UI displaying details
about only the specific
reservation.
Before launching your app, we
wrap the intent in an
INInteraction and NSUserActivity
object.
With the activity type, set the
name of the Intent and launch
your app using that, like we saw
in the demo.
So, we looked at how Siri uses
the reservation details you
donate, and how that information
is used later on to launch your
app.
But as we know, life happens.
A user might change or even
cancel their reservation, and
that can happen inside or
outside your app.
For instance, from a web page.
Let's take a look at how to
handle some of those cases.
First, let's talk about when is
the right time for your app to
donate.
In this example, the user is
looking at details for a
specific reservation.
Now, this is an excellent time
for your app to donate, because
like we saw earlier in the demo,
we might show a notification to
the user.
Seeing the notification and the
reservation details at the same
time provides a great contextual
user experience.
But life also happens when your
app is in the background, and
users should always have up to
date information.
So a new or updated reservation
information becomes available,
donate that from the background.
In that case, we won't show a
notification to the user.
So those are great times for
your app to donate, while there
are some not so great times for
your app to donate.
As we showed earlier in the
demo, your app should not donate
when showing a list of unrelated
reservations.
Showing a notification at that
point might surprise the user
because of a lack of context.
To provide a seamless
experience, your app should not
provide UI elements that
explicitly donate to Siri.
In this example, the app should
donate when the reservation
details are being displayed.
Next, let's look at some changes
that might happen to the
reservation.
Here, we use the example of a
user selecting a seat for a
flight.
We previously donated this
reservation.
At the time, seating information
was not available, so we set the
seat property to nil.
Now, the user has selected a
seat, so we are going to donate
the updated reservation details
with the seating information
set.
Keep in mind that the item
reference must remain the same
throughout the reservation life
cycle.
Once donated, Siri will
propagate this information to
all the relevant places,
including Calendar.
Next, let's talk about
cancellations.
Cancellations are a special type
of modification.
In this example, we already
donated this reservation with a
status that confirmed.
Unfortunately, the user had to
cancel the reservation.
So we are going to donate the
updated reservation details with
a status set to cancel.
Like with all modifications, the
itemReference must remain the
same.
So, that's how your app should
handle some of the things that
can happen during the
reservation life cycle.
Now, let's summarize what we
talked about today.
So, we've seen how easy it is to
take advantage of the Siri Event
Suggestions API, and how we
provide a great user experience
throughout the reservation life
cycle.
Here are the three main
takeaways.
Your app should donate
reservation details when they
are displayed to the user, or
when they are received in the
background.
Make sure you keep your users up
to date by donating when the
reservation details change.
And finally, remember to handle
app launch, so the users can get
back into your app at the right
time, and the right place.
For more information, and to get
access to our sample code, you
can visit our session link on
the Developer Portal.
We also have some related
sessions from previous years
that we encourage you to check
out.
Thank you, and I hope you had a
great conference.
[ Applause ]