Whether you're hosting event information in your app, on the web, or in an email, Siri Event Suggestions can help people keep track of their commitments — without compromising their privacy. We'll show you how to set up your reservations so that they automatically show up in the Calendar app and how to work with the Siri Event Suggestions APIs for iOS and Markup for web and email.
Hey. My name is Sofiane. I work on Proactive Intelligence here at Apple, and today, I'll be joined by my colleagues Romain and Magnus to tell you about how we make integrating your reservations with the system really easy, and all of the great benefits that come with it. We first introduced the Siri Event Suggestions API last year in iOS 13, and over the past year, we've seen some great adoption of the API in your apps. But we've also listened to your feedback and made a ton of improvements. So let's dive right in. So, what is Siri Event Suggestions? At its core, the feature makes it super easy to get reservations from your app into Calendar.
All someone has to do is make a reservation in an app, like they normally would, and it'll magically appear in Calendar, just like that. The system then uses on-device intelligence to streamline everyday interactions with your reservations. So, for example, on the lock screen, Siri can notify you when it's time to leave for a restaurant reservation, based on local traffic conditions. And when you open Maps, you get a Siri Suggestion, so getting directions to the airport to catch a flight is as easy as just one tap.
Siri can also proactively suggest turning on Do Not Disturb, so you can stay focused on what matters, like the movie you're about to watch. And Siri can even provide a suggestion to check-in for your flight right on your lock screen. Today, we're gonna talk about some of the enhancements we've made to make your life as a developer easier, as well as some of the improvements we've brought to the user experience.
We're gonna break the talk down into four broad segments. We're gonna go over some exciting updates on reservation categories and how we've expanded to more platforms. Next, my colleague Romain will introduce a brand-new way to use web markup to integrate with Siri Event Suggestions on your website and emails.
We've also gotten great feedback from you over the past year, so Magnus will speak to some donation best practices we know you'll be interested in. Finally, we have a short segment where we'll share some tips and tricks to make debugging easier. All right. We've got a ton of great content, so let's get started. We already support a wide range of categories, from restaurants, to flights, to event reservations, and this year, we're expanding transit support to include bus and boat reservations. As with train reservations, these are not meant to represent things like an all-day bus ticket, but instead, trips that are booked for a specific time. In addition to supporting more reservation categories, we're also expanding to new platforms. This year, we're delighted to bring Siri Event Suggestions to macOS Big Sur. You can use the Intents framework to donate your reservations in your app, including apps built with Mac Catalyst. And just as with iOS, all you need to do is donate your reservations to the system. And just like that, people will get all of the same on-device intelligence they do today, like getting a reservation in Calendar, Siri Suggestions, and more.
And if you have an iOS and a macOS app, you should still donate your reservation on all platforms. As long as the data you're donating is consistent, the system will make the cross-platform experience seamless by automatically syncing reservations across all devices using end-to-end encryption. By popular demand, we're also making development easier than ever by enabling you to use Simulator. Just select the simulator as a target, and build and run your app as you normally would. The Siri Event Suggestions API is offered as part of the Intents framework, which is available for apps on iOS, and now on the Mac as well.
You can check out last year's session "Integrating with Siri Event Suggestions," which covers this topic in-depth, and is a great way to get started with the API.
We really want everyone to benefit from the same on-device intelligence, regardless of how they're making or accessing their reservation information. And we know you interact with customers through many channels. Someone might start by making a reservation on your website, then later modify it using your app, maybe check it from a confirmation email. And that's why we're thrilled to announce that we're introducing new ways to integrate with Mail and Safari. All you need to do is embed web markup within the HTML of your website or emails, and it just works. And now I'd like to invite my colleague Romain to tell you about how to use markup to integrate with Siri Event Suggestions on your website and emails. Romain? Hello, everyone. My name is Romain, and I'm going to walk you through how to add markup to your website and emails for Siri Event Suggestions. This is new in iOS 14 and macOS Big Sur.
Now, when you view a reservation in Safari, the system will look for markup you've added and automatically add the reservation to Calendar.
In Mail, reservations are intelligently added to Calendar in the background, without even having to open the Mail app.
We even display a useful banner at the top to make it easy to see the most important information at a glance. We're leveraging a web standard called schema.org. Schema.org is a standardized markup vocabulary which makes it easy to annotate reservation information on your website and emails. And because it's a standard, it can be used by any email client or web browser, even on other platforms. Adding markup is easy, and we support both JSON-LD and Microdata. We created documentation about the specific categories and properties we support, as well as some examples to get you started on developer.apple.com.
Let's have a look on how to add markup to your emails and web pages. Here's an example of a confirmation email for a restaurant reservation. This email has lots of useful information.
For example, we have the name of the restaurant, the date and time of the reservation, but also the phone number and address of the restaurant.
And so, this is what the complete JSON-LD markup looks like. So, the more details you provide in the markup, the better user experience we can provide. For instance, knowing the address of the reservations means we can notify the user when it's time to leave.
And here's the same markup, but using Microdata. When a user changes or cancels a reservation, it's important to keep the markup up to date.
For a modification, the markup should represent the updated reservation information. As long as you keep the same reservationId, Siri will automatically update the Calendar event.
In our example, the user modified the time of the reservation from 7:30 to 6:30 p.m. So we're reflecting that in the startDate property, while keeping the same reservationId.
If a user cancels a reservation, set the reservationStatus to ReservationCancelled and Siri will automatically cancel the Calendar event.
Now, you have all the tools you need to add markup to your website and emails. Great! Next, let me tell you about our requirements.
First, you must register your domain with Apple. For that, we've created a simple form on developer.apple.com where you can submit your domain and samples of your markup.
We also require that your website uses HTTPS, and that your emails have a valid DKIM signature. With that taken care of, Safari and Mail will donate your reservation to the system.
We also added two settings that disable this requirement to make testing your markup in development super easy.
First, to enable your domain for testing, open the Developer Settings and enable Allow Any Domain on iOS, or use the command below on the Mac.
Likewise, for local development, you can enable Unverified Sources in the Developer Settings on iOS, or by using this other command on the Mac.
Now, let me show you how all of this comes together.
As I mentioned before, to test the schema.org markup in my development environment, I'll need to do some prep work. First, I'll set the SuggestionsAllowAnyDomainForMarkup default which will allow for unregistered domains.
Great. Next, since my local environment doesn't use HTTPS, I'll set SuggestionsAllowUnverifiedSourceForMarkup, enabling unverified source verification check.
In this example, I'll be using a website that handles restaurant reservations, which already has schema.org markup embedded. Let's find a restaurant. This one looks good to me.
Let's make a reservation for this Friday for 7:30PM. For two. I'm going to make the reservation.
The website allows me to review that all the information is correct, and because the reservation isn't confirmed at this point, it won't be added to Calendar. This looks all good to me, so let me go ahead and confirm the reservation.
Since my markup now contains a confirmed reservation, Safari is donating the reservation to the system, and I'll get this handy Calendar notification.
Let's have a look at the Calendar event Siri just created.
By clicking on the notification, I can see all the information I need. Let's add it to Calendar.
If your markup contains a URL, the system can provide it as a link in Calendar, so I can quickly get back to my website to access and manage the reservation. When I click on it, it goes right back to that specific page.
Let's have a look at the markup on this page, using the Safari Web Inspector to view the source code.
Here you can see the JSON-LD tag. It contains all the information about the reservation.
You can see that the reservation is confirmed, the reservationId, and also the URL we use for the "Show in Safari" link we just saw.
There's also the start time of the reservation, which uses the ISO 8601 format, including the time zone of where the reservation is happening.
Now, let's say the user changes their mind and wants to cancel their reservation.
It's really important here that the markup reflects this change. The reservationStatus is updated to ReservationCancelled.
And just like that, the Calendar event is automatically cancelled in Calendar. This feature also works great in Mail. We've included the same schema.org markup in the automatic confirmation emails sent from our demo website. Let's have a look at this on iOS.
I just received the email confirmation about my reservation being cancelled. I'm opening it. And you can see at the top, Siri detected the event, but knows it's cancelled. With just one tap, I can delete the Calendar event directly from the banner.
And it's gone. The key takeaway here is to keep the same reservationId for confirmation, updates, and cancellation. And that's how easy it is to integrate with Siri Event Suggestions using markup on macOS and iOS. Now that you know how Siri Event Suggestions markup works, I wanted to highlight a few key points.
It's important to respect the format and type of each property as defined in the developer documentation. And here's a few examples. First, use the appropriate reservationStatus. For example, use the ReservationConfirmed status only when the reservation is confirmed. In some cases, that might mean making sure payment has been processed.
For date times, we all know this can be tricky, so here, it's important to use ISO 8601 format, including the time zone of where the reservation is happening.
And make sure all markup for a reservation use the same reservationId. This will allow Siri to update the user's Calendar event, if the reservation is modified or cancelled. Now that you are ready to integrate with Siri Event Suggestions, let's talk next steps.
Again, make sure to add markup that accurately reflects your reservation details, including the correct status.
Use Developer Settings to test your markup locally.
And finally, once you've verified your markup is working register your domain with Apple, so people can start enjoying an even richer experience, interacting with your reservations. And now, I'll hand it off to my colleague Magnus to talk about donations best practices. Thank you, Romain. Since releasing the API last year, we've seen some great adoption. We also heard some helpful feedback from you about what features you'd like us to add, and what some of the challenges were when adopting the API. In this section, I'd like to talk about some of the best practices for providing a great user experience.
Let's start with a quick refresh on how the API works. Integrating with Siri Event Suggestions starts with the reservation details in the app. As an example, I'll be using this made-up restaurant booking app to walk through a typical donation flow.
To donate to Siri, the app first maps its reservation details into INReservation objects. The INReservation object is shown in green here, and contains the details about the reservation shown in the app. To keep it simple, we're only showing the itemReference in this example.
The INReservation objects are added to an intent response that together with the intent forms the interaction that the app donates to Siri. Once donated, Siri may create one or more Calendar events and notify the user that the reservations were added to their Siri Event Suggestions Calendar.
Now the user has access to some of the most important details right in Calendar.
To get more details, or to manage the reservation, we want people to easily get back into your app, so we put a "Show in App" button right in Calendar to make this easy.
When the "Show in App" button is pressed, the system will construct an INGetReservationDetailsIntent containing information about the reservation the user wants to view.
The intent uses the container and item reference from the donation that was used to create the event.
The app is then launched to the foreground with the user activity and interaction with that intent. The app uses this information to display the right reservation to the user.
As we've seen, the container and item references are used to launch your app. Let's take a look at some more details on how the two are different from a similar INReservation property, the reservation number. The reservation number is used by Siri to identify changes to a reservation across sources. For instance, if you support both the Siri Event Suggestions API in your app, and the Siri Event Suggestions markup in your emails or on your website, make sure the reservation number is the same in all places.
Similarly, if a reservation is updated with new information, or is cancelled, Siri uses the reservation number to identify which Calendar event to update.
Like we talked about earlier, the container and item references are used for launching your app. The container reference uniquely identifies a reservation within your app. That reservation may consist of one or more parts. For example, in a flight reservation with multiple legs, each leg is one part of the reservation and must be represented as an individual INReservation object with a unique item reference.
The reason the item reference must be unique is that the system may launch your app to display a single part of a reservation, like one of the two legs from that flight reservation.
Now that we have an understanding of what the container and item references are for, let's take a look at some concrete examples of reservations and how we can choose good values for them. I'll use the app we saw in the previous section as an example. In this app, users make restaurant reservations like the one on the screen. For this reservation, the reservation number identifies all parts of the reservation, which in this case is only one. So, I'll use that as the containerReference.
When there's only a single part in the reservation, I can make the itemReference the same as the containerReference.
I'll also set a descriptive spokenPhrase for the reference, in this case "Table at ACME Eatery." This'll be used if the reference needs to be displayed, like if the user makes a shortcut to launch this reservation. Again, I use the same value for both references.
Next up is an app for booking transit reservations, like this round-trip train reservation shown here.
This reservation has two parts, one part for each leg of the trip.
Like in the previous example, the reservation number identifies all-- in this case two-- parts of the reservation, so I'll use that as the containerReference and make sure I set a spokenPhrase that also describes all parts of the reservation.
For the two legs of the trip, I'll create two TrainReservation objects. Since there are two parts but only a single reservation number, I can't use that as the itemReference like I did in the first example. Instead, I'll have to pick an identifier that's unique to each part of the reservation. In this case, I'm using the ticket number associated with each of the two legs of the trip. That way my app can easily determine which leg to show if it's being launched to show just one of them. I also set a spokenPhrase that describes each of the legs. Finally, some apps allow users to book reservations with multiple different categories, like a travel-agency app offering bundles of transportation, lodging, and so on. In this example, the reservation has three parts: two flight legs and one hotel stay. In addition to having three parts, the reservation also has three reservation numbers. One is for the two flight parts, one is for the hotel part, and one is for the whole trip. The containerReference should identify all parts of the reservation. So, in this case, I'll use the reservation number for the trip.
For the flight, I'll create one flight reservation for each leg.
Like in the previous example, the two legs share the same reservation number, so I can't use that for the itemReference. In this case, I'll create a new identifier combining the reservation number and the flight number and use that for the itemReference. You can choose any identifier you'd like here, as long as it's unique and it enables you to find a specific part of the reservation to show when being launched.
For the hotel part of this reservation, I'll create a LodgingReservation object. The reservation number for the hotel is only used for that one part of the reservation. Since it's unique, I'll use that for the itemReference.
Now we've seen a few examples of how to set the container and item reference so your app can provide a great user experience and show the right part of the reservation when being launched. Next, let's take a look at how this experience changes, if the calendar event is being displayed on a device where your app is not installed. This year, we added a new URL property to the INReservation class. If a Calendar event that was created from one of your app's donations is being displayed on a device where your app is not installed, and the reservation you donated included a URL, we'll display a "Show in Safari" button in Calendar. Instead of launching your app, pressing this will open the URL you set in Safari, so the user can view their reservation details on your website.
Make sure you adopt this new URL property, since calendar events will be synced to all the users' devices, some of which may not have your app installed. That way you can still provide a great user experience. Providing a great user experience also means donating at the right time and place in your app. That will give your users the necessary context if a notification is shown, and it makes sure the system has up-to-date reservation details. This year, we made some changes to how notifications are shown, so your app can donate multiple interactions containing reservations. Now, the system will intelligently group notifications when multiple donations are made within a short amount of time. The ideal place to do this is when your app is displaying a list of upcoming reservations.
We also recommend you donate when viewing a single reservation and when viewing a specific part of a reservation, such as one of the two tickets for this movie. The system will only show a notification for a reservation the first time it's donated. Another great time to donate is in reaction to the reservation changing outside your app. Doing this means your users' data is as up to date as possible, both in your app and in the system, by donating to Siri. There are two complementary ways of achieving this, and Apple offers great APIs for both. Your app can use the Background App Refresh APIs to periodically check for updates and donate to Siri in the background.
Your app should also adopt silent push notifications so it can react to changes as they happen. When a silent push notification is received, your app can refresh its reservation details and donate to Siri. For more information about these APIs and other information related to background execution, please refer to the "Advances in App Background Execution" session from last year. So that's donation best practices. Next, I'd like to talk about how to debug issues when donating reservation details to Siri. When your app donates reservation details, they may be processed asynchronously by different parts of the system, so it's not always possible to let your app know if something went wrong. To help you debug issues during development, we added extra logging for some of the most common issues we've seen and heard about from you. You can view these logs in the Console app in Mac OS.
To only show logs related to your donations, set the search filter to the category "siri-event-suggestions." Let me show you a quick demo of how this works.
So, here I am in the sample app. I want to try out the new bus reservation type we added this year, so I've added a createBusReservation method. So far, I made some helper methods to create the two bus trips I'm making the reservation for.
And here, I'm creating the reservation objects.
Finally, I'm adding them to the list of reservations in the app.
Let's run the app and see it in action. New in iOS 14, we added support for using the Siri Event Suggestions API in the iOS Simulator, so I'll use that.
To run the app in a simulator, I simply select an iOS simulator from the list of devices next to the target. And press "run." Looks like my bus reservation is visible in the app. Great. I'll press the reservation to show more details. That will also donate the reservation to Siri, so I should see a notification telling me Siri has created an event.
I'm not seeing a notification, so something must have gone wrong, but I'm not sure what or why. Starting with iOS 14 and macOS Big Sur, we added extra logging to help debug donations like this. To see what's going on, I'll first open Console.
In the Console app, I can choose which device to see logs from, and how to filter those logs. I want to see logs from my simulator, so I'll select it from the list of devices.
There's a lot of logging going on in the system, so we created a logging category for Siri Event Suggestions. By setting this as a filter in Console, I'll only see the messages related to my donations. To use this, I go to the search bar and enter "siri-event-suggestions." I also change the type of search from "any" to "category." Finally, I press "Start streaming." Let's go back to the app and try again.
In Console, I now see a log message.
Let's click it for more details. It says that two or more reservations use the same itemReference.
As we talked about in the section on donation best practices, all parts of my reservation must have a unique itemReference so my app can show the right thing when it's being launched.
When I wrote this code, I copy-pasted the part to create the second reservation. I forgot to change the itemReference. They're both "ABC-001." To fix this, I'll change the itemReference of the second object to "ABC-002." Keep in mind that in the production app, you would likely get these values from a database or a server. But for the sake of this example, I'm using some simple hard-coded values. Let's run the app again.
I'm still not seeing a notification, but it looks like there's a new log entry in Console. Let's look at the details.
It tells me I haven't acknowledged the What's New in Calendar screen. Siri won't add events to the calendar until the user has done this, and I haven't used Calendar on this simulator before. So let's open Calendar and do that.
That should do it. I'll go back to the app and try again.
And there we go! I now see a notification telling me Siri has added the reservations to my calendar, and if I press the notification, I can see that both parts of the reservations are in my Calendar inbox. That's great. Debugging issues in the Console app isn't just useful for the Siri Event Suggestions API. It can also be used for the new markup support that Romain talked about earlier. Let's take a look at a quick example. I'll open Safari. Here's the reservation site from earlier in this session. I'm gonna make a reservation for two at this restaurant and confirm it. Since this page contains markup with a confirmed reservation, I'm expecting to see a notification telling me Siri has added the reservation to my Calendar. But like before, I'm not seeing one, and I'm not sure why. To debug this issue, I'll bring up the Console app again. This time, I need to set the device to my Mac.
When I change the device, I also have to set up my filter in the search field again.
And press "start." I'll go back to the web page and reload it. That way, Siri will read the markup again.
I'll then switch back to Console to see if there's anything in there to help me understand what's going on.
I now see some log entries. I'll press the most recent one. It tells me the end time of the reservation has already passed. Siri won't add events to the calendar if the reservation has already ended. I'll go back to the website, and, sure enough, it looks like I tried to make this reservation for yesterday. I'll update it to tomorrow...
And there we go. I now see a notification telling me Siri has added the reservation to my Calendar. That's how you can debug Siri Event Suggestions to catch some of the most common issues, whether you're using the API in your app, or markup in your emails or on your website. Now I'll hand it back to Sofiane to wrap up. Thank you. Thanks, Magnus. We talked about a ton of great updates today, so let's wrap up. We added support for bus and boat reservations, and we've made it possible to donate your reservations on macOS for a great cross-platform experience. We've introduced a new way to add markup to your website and emails, which will enable the same intelligent user experience people love, no matter how they're accessing their reservation information. And finally, we've enhanced the experience for you as a developer by making it easier to debug using Console and test your adoption using Simulator. We talked about how to best donate your interactions, and how the new URL property can provide a great experience even if your app is not installed. We can't wait to see how you take advantage of all of these improvements. Thank you!
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.