VIPUL PRAKASH: Hello.
Welcome to session 709.
I'm Vipul Prakash and I'll be joined by my colleagues Dave Salim and Jason Douglas.
We'll give you an in-depth tour of the new Search APIs in iOS 9.
As you saw in the Keynote, deep links, the content in your apps, they can now appear as tightly integrated search results in Spotlight.
This is tremendously exciting.
On iOS users spent most of their time inside of apps, this is where all the great content is, this is really where people live their digital lives these days.
We have been interested in connecting all of this great content through Search.
We didn't want to create an ad hoc one-size-fits-all course of indexing scheme going inside of your apps to grab whatever it can and stuffs it in Spotlight.
That's an approach to indexing that worked well for the web because it is uniform but it is the wrong approach for app search.
What we wanted to do was create an experience where you as developers choose exactly what is in the index, how results appear in search and where the user goes to when they tap on the results.
I think we have been able to achieve this with search APIs keeping them simple and lightweight.
The goal of search APIs is to bring the content in your apps more deeply in a search context.
In addition to results appearing in Spotlight they also appear in Safari.
This works in a way similar to how Spotlight suggestions work which are produced in iOS 8.
As the user types a query into the Safari address bar, you have the results from the Internet like Maps, Wikipedia, App Store and the user can tap on the results to jump directly to the content they're looking for.
In iOS 9 users will be able to jump directly to content inside of your apps.
This is another vector of distribution and exposure we provide.
Public deep links inside of your app, will now appear in search results for users that don't have your app installed.
This is super exciting.
This provides a whole new level of exposure for your app potentially to hundreds of millions of iOS users.
VIPUL PRAKASH: Let's look at how this works.
Let's look at examples.
We invited the folks from Airbnb to look at the APIs and they were able to do an integration within a few hours.
What they did, they took reservations that users make and the communications that they have on the platform and index them to the search APIs.
Now when I look for the reservation I made in Napa, I put that in Spotlight, the reservation comes up as the first result.
It has the dates it is really cool.
VIPUL PRAKASH: It has the dates, number of guests, descriptions, and when I tap on it it takes me inside of the rich experience in the app.
Another result that you will see here, this is result number 2, which is a message from the host of the reservation.
As you can see, I can read the message, it is very useful and there is also a call glyph on the right, when they indexed this, they are added data to include the phone number of the host and Spotlight picked this up, rendered a call glyph and when it happens, it does what you expect.
It makes the call.
So this is a really beautifully integrated integration to achieve search APIs.
Let's look at other examples.
Here is LinkedIn, a professional networking app.
What's happening in this example, my first degree network, all of the communications that I have had on LinkedIn have been added to the search index.
Now they're available in the same way as built-in Contacts and built-in messages that are available.
Now search APIs, are not limited to just content.
One really handy use case is to make navigation points and features inside of apps searchable.
As an example, our very own Health app does this.
It indexes all the deep links of all the sessions.
If I want to see how many steps I have taken, I type steps in Spotlight, get this deep link, tap on it, go straight to the steps screen.
VIPUL PRAKASH: I think this is very cool.
One of the most popular users of Spotlight Search is to find and launch apps.
We believe in iOS 9 going straight to deep navigation points inside of apps is going to be another very popular use case.
In all these examples the results came from your own device index, the deep links were put in the device index and they never crossed the device boundary.
What if the user does not have your app installed?
We maintain a massive index of deep links in Apple's cloud servers.
We can serve results seamlessly from this index.
We have come up with a novel way of populating this index.
Developers, you can tag content which is public as public and once enough users engage with it, it is then promoted to the cloud index where now it is available to all users of your app and if there are web links associated with the deep links then it is available to all users of iOS.
Now indexing and crawling apps is nonsensical in some ways but on the web, it is not.
If your app mirrors its content on a website what we can do is go out and proactively go index your website, find the deep links and bring them in a cloud index when they're seamlessly available in search.
This logic of seamlessness of on device search and cloud search, it is very important to the App Search story.
There is a lot of content in apps that's private and then content that's public, it is not both at the same time.
What we can do with this approach is present a seamless search interface to the user where the results are coming from the device index or the cloud index.
Let's look at examples of this.
I searched for "northern lights" a music festival, I'm presented with a result from the cloud index from the EventBrite app, I don't have this app installed, this result has a web link.
I tap on it, it takes me to Safari and opens the space.
You notice that EventBrite users, the smart app banner which encourages me to download the app and experience this content in a richer way, which is what I do now.
Imagine if this was your app, wouldn't it be awesome to get your content in front of all iOS users in this very contextual way when they're looking for something that your app provides to promote app discovery?
Here is an example where I searched for "sprained ankle".
I don't have an app for medical conditions on my device.
I'm offered multiple results by App Search based on the apps that users have previously found interesting or useful for this query.
I can tap on this, install the app and continue my exploration inside of the app.
So how does this work?
App Search has three APIs that are distinct but related.
They're designed for enabling different use cases of App Search.
The first one is NSUserActivity.
This is an extension of the Handoff API that we released in iOS 8.
When we looked at the pattern of information access and search one of the things we found is that users want to search for things they have seen in the past.
NSUserActivity makes searching this information and indexing it very easy.
It sort of works like how a web browser maintains your browsing history and the user activity maintains the form of app history and makes it searchable.
The second API is called CoreSpotlight.
This is a very powerful way of comprehensively indexing any content inside of your app.
All built in apps in iOS 9, Mail, Notes, Calendar, they use this CoreSpotlight.
It gives you low level access to the index on the device, it sort of works like a database API you can add and remove items, and it's the best way to index any private content that you have inside of your app for the user.
Third API is web markup.
This is for apps that mirror their content on a website.
You can simply markup your web content with deep links, annotation information, we go out, crawl it, put it in the cloud index and it is then seamlessly available to users through iOS 9 search.
Here is the Agenda for the rest of the session.
We'll do a deep dive into each of these APIs, show you how they work, and we'll look at how best to adopt these APIs in your apps.
To talk about NSUserActivity and CoreSpotlight, I would like to ask Dave Salim.
DAVE SALIM: I'm Dave Salim, a developer on App Search.
We just heard about some exciting new features to make the content in your apps searchable and more discoverable.
Now we'll take a look at some of the APIs you can adopt to enable these features.
We'll start off by taking a look at NSUserActivity.
A little background, NSUserActivity was introduced in iOS 8 to support Handoff.
Handoff is the amazing feature that allows you to start an activity on one device and pick up right where you left off on another.
NSUserActivity is a lightweight way to capture application state which can be restored later.
Now new in iOS 9 is we're adding the ability for NSUserActivities to be indexed and searchable from iOS search and Safari.
You will now be able to associate metadata with your activities so you can describe your activities.
And that information can be used to index and provide rich search results.
When users engage with your search results, your app will be launched and passed the activity with that result.
You can continue restoring the state bringing the user right back to its content.
Let's take a look at an example of how NSUserActivities are added to the index.
Here we have a recipe app and as a user browses a recipe in this app, we create an NSUserActivity capturing its state, providing it the information needed to get back to this recipe.
We then describe that activity with information from the recipe, the title, description, even a thumbnail.
Then we inform the system that this activity represents the user's current state and that activity is added to the on-device index.
So as a user moves about the app we follow the same pattern of creating activities, describing them, and informing the system that these represent the users current state and these activities will be added to the on-device index.
Let's take a look at some of the new and existing properties on NSUserActivity used to support App Search.
First, there is now properties to designate an activity's capabilities, there is one for Handoff, by default Handoff is enabled, if you choose not to enable Handoff for your users, you can easily set this to false.
There is one for search which allows on-device indexing of the activity.
There is one for Public Indexing which we'll talk about in a minute.
Next, how do you describe your activity?
First you give your activity a title.
This title is used both for indexing and for display in the search results.
You can also provide keywords to describe your activity, these will also be indexed.
To fully more describe your activity you can use a new class we're introducing in CoreSpotlight named CSSearchableItemAttributeSet which makes it easy to describe the activity by setting properties and you can set this on the contentAttributes property of NSUserActivity.
If you prefer for your activity to only be shown until a certain date, you can provide an expiration date.
Also if your activity's content can be restored on the web or you support Safari's universal links, set the webpage URL property and the system will appropriately launch your activity in Safari or in your app.
Now let's take a look at how we create an activity.
Here we're instantiating an instance of an NSUserActivity and we're providing it an activity type.
This is a unique string that you provide, this is the same string you provide to the system to let it know what activities your app is capable of handling.
We recommend a reverse DNS-style notation for these types of strings to keep them unique.
Next, our activity needs a title.
Again, the title is used for indexing and used as a display title in the search results.
Next, we're setting a dictionary on the userInfo property containing the information we need to recreate the state.
Next we're enabling on-device indexing of the activity by setting eligibleForSearch to true, and with this activity it represents what the user's current state is and we inform the system by becomeCurrent on the activity and the activity will be added to the on-device index.
What does this look like for your users?
Now users can be returned search results for activities indexed from your apps.
Here we can see how the title property maps to the title in the search result and if you provide more information using the contentAttributes set we can provide richer results.
So now what happens when a user taps on one of your search results?
A UI application delegate method in your app is called, the same one used for Handoff.
Here we see continueUserActivity restorationHandler.
And we pass that activity for the search result.
We check its activity type and we can continue to restore the state using the information populated in the user info.
So now users can tap on results for activities from your app and you can restore them right back to the proper state.
NSUserActivity in App Search is a great way to let your users get back to the content they previously visited.
We wanted to take it a step further.
So when we were designing this feature we took a look at a lot of apps in the App Store and noticed a lot of apps have content that's available to many other users.
So we thought wouldn't it be great for discoverability if we could take the activities representing public content and make them searchable by all users of the app not just ones that previously visited that content?
That's what we're doing with NSUserActivity and Public Indexing.
So how does this work?
As a user navigates the public content in your apps you create NSUserActivities capturing that state and you designate them as public.
As users engage with the search results for these activities the activity is shared with our cloud index and made searchable by all users of the app, not just ones that previously visited the content.
If your activity can be restored on the web and you set the webpageURL property you can massively increase its audience by being searchable in iOS Safari.
So let's see how we designate an activity as public.
We can start off with the activity we previously saw and we can set one additional property.
Here we're setting eligibleForPublicIndexing to true and we just designated this activity as public.
Even though we have set this property to true, that doesn't mean that the contents of the activity are immediately shared with our cloud index.
For an activity to be shared it first needs to appear in search results and be engaged with by many users.
We track these engagements using a zero-knowledge proof method which keeps the activities' contents private until an engagement threshold is met.
So here in more detail as a user engages with the search result for an activity designated as public a one-way hash of the activity is sent to our cloud index.
Not until the cloud index has seen the same hash many times from users is the content of the activity shared with our cloud index.
We took extra measure in defining the feature this way first to respect user privacy and second to prevent any user specific data from accidentally being shared with our cloud index.
In addition, the properties on NSUserActivity eligibleForSearch and eligibleForPublicIndexing are false by default and for everyone here, only designate public on your activities that represent content and features that are popular among many of your users.
Now let's take a look at some additional benefits you get for adopting NSUserActivity.
The first is Handoff.
So by adopting the API you've just added support for Handoff.
If you choose, you can allow your users to start an activity in your app on one device and continue it on another.
The next two are related to new features from Siri.
As shown in the keynote, swiping left of home presents the user with Siri suggestions.
Along with suggested Contacts and suggested apps and nearby places, activities from your app can be suggested.
Here we see a suggestion for an upcoming calendar event and a suggestion to resume a podcast.
Next is the Siri smart reminders.
Now users can ask Siri to remind them of specific content from your apps and when they do the activity from your app is embedded in the reminder.
It is an easy way for users to get back to the content they want to be reminded about.
NSUserActivity in App Search makes it easy for your users to get back to the content they previously visited and it can make the public content in your apps more discoverable.
Next let's talk about the next API you can use to make the content in your apps searchable, that's CoreSpotlight.
CoreSpotlight is a brand-new framework on iOS 9.
It provides a database-like API so you can add, update, delete items.
The items you indexed using CoreSpotlight will be searchable in iOS search and it is used by our own built-in apps, Messages, Mail, Calendar, Notes, you can get an idea of what you can index with CoreSpotlight.
Let's take a look at the API.
First we start off with a CSSearchableItem.
This will represent the unique item we wish to index.
Next we associate a CSSearchableItemAttributeSet which is an easy way to describe the item by setting properties.
Then we pass the CSSearchItem to the CSSearchableIndex and the item is added to the on-device index.
Let's see how we go about creating an item.
First we start off by creating the CSSearchableItemAttributeSet.
Here we have one for an image.
Next we set a few properties on the attribute set to describe the item we wish to index.
Here we're setting a title and a description.
We'll see how the title and the description map to the search result in a bit.
Next we create the CSSearchableItem and we supply a unique identifier, this is an identifier that the app can use to reference the actual data that we wish to index.
We can supply a domain identifier.
This is a way of grouping items together.
In our example here we're indexing a photo.
We may want to group all of our photos together under a domain identifier representing an album.
And we provide an attribute set which we created above describing the item.
Next, we index the item calling indexSearchableItems on the CSSearchableIndex passing it an array of items we wish to index.
What does this look like for users?
Users can now go into iOS search and be returned search results things in your app that have been indexed using CoreSpotlight.
Here is how some of the attributes, properties we set on the attribute set map to the search result.
What happens when a user taps on one of your search results, a UI application delegate method in your app is called, the same one used for Handoff and here we see again ContinuousUserActivity RestorationHandler and this time you know you're being launched by a CoreSpotlight item because the activity type is set to CSSearchableItemActionType and the unique identifier we used when we initialized the searchable item is accessible for the value in CSSearchableItem ActivityIdentifier in the userInfo.
So now users can tap on search results and you can return them to the right context for that item.
Now let's talk about maintaining your index.
The index supports updating items.
Over time the title of your item may change, the description may change, the user updates, certain fields of your representing your item, you can update them by calling the same method you used to index items by creating a CSSearchableItem with a unique identifier that you wish to update associating an updated CSSearchableItemAttributeSet and indexing the item calling indexSearchableItems.
Another common maintenance routine is deleting items.
It is good practice to delete any items that are no longer relevant from the index.
We support multiple ways to delete items.
First, you can delete by identifier so you can pass an array of identifiers to delete searchable items with identifiers.
Those items will be deleted from the index.
You can delete by domain identifier.
You saw earlier when creating our item, you can use a domain identifier to group items together.
You can pass the identifier and the group of items will be deleted when calling deleteSearchableItems WithDomainIdentifiers.
Last, you can delete all the items from your index by calling deleteAllSearchableItems WithCompletion handler.
Now let's take a look at a demo to see how easy it is to add CoreSpotlight to your apps.
Our demo app is a photo viewer displaying a collection of photos.
I'll show you how easy it is to index the items by their title and we'll look at the user experience of searching and restoring.
Here we have Xcode and the iPhone simulator.
Let's launch our app first to get an idea of what it looks like.
Here we have a collection of photos, each photo has a title below it.
There are some nice sunsets in here.
Okay. Let's see how easy it is to index these photos using their title.
You go in Spotlight, and we have a method, index items and we'll call this when the data model initializes and we'll enumerate over all of the photos in the data store and we'll add each photo using CoreSpotlight.
We'll start off by creating the attribute set describing the photo.
Here we're creating a CSSearchableItemAttributeSet for an image.
Then we'll take the title from the data model and set it on the Title property of the attribute set.
We'll also include a description based on that title.
Next we'll create the item itself.
Here we're passing in a unique identifier which represents that we can use to reference the image in our data store.
Then we'll call indexSearchableItems passing in the item into the CSSearchableIndex.
Now let's build and run this app and here we are back in our app and this time when our app initialized it called index items and enumerated all of the photos in the collection and added each photo to the on-device index.
Now we can go into iOS search and I remember seeing some nice sunsets in there.
We can see results from our app for these sunsets with the Title of "sunset" in them.
Tapping on one of the results allows us to restore the app right back to the proper context for that item.
DAVE SALIM: That's how easy it is to index items using CoreSpotlight.
So some additional features in CoreSpotlight is support for batching.
Your app may choose to index a large number of items and wish to break it up in batches.
The index supports saving the State of where you are in your batch process and retrieving it so that you can resume where you left off.
There is also support for a delegate and extension so that the index can communicate with your app in the foreground, background, or when it is not currently running.
There is support for data protection classes so you can choose the appropriate security policy for the information that you're indexing.
CoreSpotlight is an easy to adopt database-like API which you can use to index any features and content from your apps.
So now I'll hand it over to Jason Douglas talk about the third API, web markup.
JASON DOUGLAS: Hello.
My name is Jason Douglas.
I'm from the Siri team.
We'll talk about web markup.
You have seen two amazing ways to make your app contents searchable both in NSUserActivity and CoreSpotlight, the third set of those APIs is web markup.
And this is for content from the app which is also available on a website.
The key to making this connection is a mobile deep link.
A deep link is a lot like a URL but rather than to a webpage it links to content, specific content directly inside of your app.
You saw this diagram earlier where we're building both an on-device index and a cloud index from public items that are sourced from the device.
Well, to call crawl content from websites Apple now has a web crawler called AppleBot which is going out and crawling app websites for quite some time now.
And for a lot of this content, you didn't have to do anything.
If your website supports mobile deep links, we were able to go ahead, discover that content and make it searchable from iOS search and Safari.
This content when pulled from the website, we surface it directly in search and Safari like you see here.
And when a user taps on one of the results they're deep linked directly into your app seeing the content that they saw from search results.
You will notice there is a link to get back to your app which you get for free.
You don't have to do anything special in your app to get this behavior.
Users simply have to tap on that link in the top left corner and they're taken back to searching.
This makes it seamless to go back and forth.
There are four simple steps to making your apps content searchable via the web markup.
The first step is making sure Apple can discover and index your website.
The second step is ensuring that your website contains markup for mobile deep links.
Next you want to also be sure that your app can handle opening those deep links and finally, this is optional, but highly recommended, is adding mark-up for structured data.
We'll talk more about what this is.
This allows your results to look rich and engaging to users.
So the first step, making your website discoverable by Apple.
We have been going out crawling the web for a while looking for sites with deep links, the easiest way to make sure we can find the app's website is to use it as either your support or marketing URL when you submit the site to iTunes Connect.
When you submit your app there is two text boxes for this.
It is very easy.
We use them as a starting point for going out and finding mobile deep links.
The next thing is making sure that your website has markup for deep links.
The most popular way, you have probably seen this before, are something called Smart App Banners, they have been around for a while.
This is a simple <meta tag specifying the app and what the deep link URL should be.
Users when they visit your app's website in Safari see a banner.
If the app is not installed it allows them to go directly to the App Store to install it or if it is already installed you can click the view button to view that content directly inside of your app.
If you want to learn more about Smart App Banners check out the Safari Web Content Guide which has more information.
In iOS 9 there is a new feature called Universal Links which is an even better alternative to Smart App Banners.
There are a few advantages over the custom URL schemes that you may have used in the past for deep links.
The first of the features is they're unique.
Multiple apps can't claim the same custom they can claim the same custom URL scheme but with universal links they can't collide because we use the app website as a way to uniquely identify.
It is secure, just because you say that an app belongs to a certain website we don't take it for granted.
A signed certificate is uploaded to the website and when the user installs your app we check the certificate to make sure that they're truly linked together.
They're also flexible so users can control the behavior whether they prefer being within the website or within the app, they can easily toggle this behavior and choose the default they want the most.
Using something like Universal Links ensures we're able to parse your deep links correctly.
The final advantage, they're universal.
A Universal Link is a single URL used both for your web content as well as your app's content.
You don't need to have two separate URLs, one for web and one for the deep link content.
If using Universal Links we'll still need to know about your deep links via your web markup, so you want to use Smart App Banners or an alternative supported standard.
This also ensures that if a user doesn't have the app installed they're still able to go discover your app, and find it, install it since Universal Links is a feature that's enabled once your app is installed.
To learn more, I highly recommend that you check out the session Seamless Linking to Your App which will be tomorrow.
So the next step or the other alternatives we also support for deep linking, one of those is Twitter cards which also uses <meta tags and Facebook app links.
In addition to just supporting smart app banners we support these as well and we'll add support for other popular standards that may come along later.
Finally, making sure that your app can open deep links.
In the past and you may be familiar with this, you may have already done this for your app, is making sure you've implemented openURL.
Here is a simple example of using openURL.
In this case in our example we have a URL which can view profiles and it simply takes a profile ID.
We simply parse the URL with NSURL components and pass the profile ID from the query parameters to the view controller.
This is a very simple example of how easy it is to support deep linking for your app.
So now I want to talk about structured data which I alluded to earlier.
Structured data is something in addition to the mobile deep link which lets us understand and parse information about your results.
Parsing freeform web text is not an easy task and this helps us out significantly.
It also ensures that your results can stand out to the user rather than just having text you can have an image, ratings, and other key things that are called out in the result.
It can also help improve your ranking because we know this result is rich and engaging to the user, we may tend to surface it more than other results.
So one standard for adding this type of structured data is open graph.
Open graph you can specify an image, an audio, or even a video file with your result.
You simply place this markup on your webpage and we'll then associate it with the deep link we also find on the same page.
Another very common format for structured data is schema.org that's been around for a while and we're adding support for it rapidly.
A common schema.org is AggregateRatings for ratings and reviews.
This example we're showing adding the AggregateRating markup with the schema.org micro data and we support RDFA as well as JSON-LD depending on what you're comfortable with implementing on your website we'll support that and parse that to be all-inclusive.
Now let's dissect an example of how this works in the real world.
Here is an Airbnb result and the first and most obvious thing is the title which we parsed with standard HTML <title tags and then we go a step further.
There is a price per night shown.
We're able to do this because on this webpage the Offer schema was added and it is associated with a hotel.
We're able to parse that price and price currency and show that directly in the result.
We're also able to show number of reviews via AggregateRating from schema.org and a rating value which we can render as stars.
Finally, the image has been provided using open graph's image tag.
So now to talk about some of the schemas which we support from schema.org.
The first is AggregateRatings, another is offers, prices, or if you have a consumer shopping site, you offer things for sale and as we saw with hotels maybe, booking, price range in case you don't have a fixed price but rather a range of prices, interactionCount for things like likes, views, comments, also interactionCount will be superseded in schema.org by the new Action set of schemas which we'll support that as well if you're thinking of migrating from interactionCount to Actions.
Organization for things such as businesses, you can also have addresses associated with these contact information, like telephone numbers and we'll see a bit later how that can help make your result more richer.
Recipes, this one is self-explanatory.
SearchActions, in case your website has a landing page for searches by marking it up in a special way we're also then able to treat your result in a little bit differently, we know it is a landing page for search.
This is for nothing else but images.
So now I want to also talk about Actions.
Actions are a way using structured data to allow your results to become actionable.
There's a set of actions that we'll be supporting on launch, the first of which is dialing a phone number, getting directions to an address and playing an audio or video file.
For the first of these examples dialing a phone number.
As we saw before with the Organization schema you can add something like a telephone as a property.
When we see this telephone number we can parse it and put a call button directly in the result.
This makes your result actionable now.
Another is using an AudioObject schema with AudioObject you can specify a URL to an audio file and the users will play it from the result, they don't have to deep link into the app and play it from there.
Finally, getting directions.
Providing a postal address we can then allow the user to navigate directly without having to deep link into the app.
This has the benefit of making your result much more potentially interactive to the user.
If a user sees a list of results and sees that they can get directly to the action that they want they may be more likely to click on your result.
So we have shown a lot of different schemas, markups, we'll add testing tools later this year for testing the markup on your website.
This will be available on the developer site later this year.
We'll be having testing tools for both the deep link markup and the structured data markup.
Finally, I just wanted to call out a few more resources as you're adding both either mobile deep links or structured data to the website, do check out some of these resources, provide a lot of information and again we'll hopefully help get you started.
JASON DOUGLAS: Now I hand it back to Vipul.
VIPUL PRAKASH: So those are three simple, powerful, and flexible ways of making your app searchable on iOS 9.
Which one should you use?
It is a function of the nature of your content as well as the kind of search experience that you're trying to create.
CoreSpotlight is for private data which is indexed on the device and you can use CoreSpotlight to comprehensively index data in your app.
If you're building or you have a social networking app for instance and you wanted to index all of the messages that the user has sent and received, CoreSpotlight is the right tool for the job.
Web markup is for apps that mirror their content on the web.
If you do that, you should absolutely adopt that markup, because it creates tremendous opportunity for your app and content to be discovered by users that don't have your app yet.
Use NSUserActivity for both public and private content as well as for indexing navigation points inside of your app.
Now there is another flavor of NSUserActivity that Dave touched on which is Public Indexing.
This is really powerful.
If your app has a large number of items, millions or even hundreds of millions you can use Public Indexing to essentially move those items and have them indexed in Apple's cloud index.
These APIs while distinct, they're really designed to work together.
In the same app for the same content you can adopt multiple APIs.
The only thing to remember is for items that are indexed from multiple places, you want to connect these items by giving them the same ID.
If you're using all three APIs, the obvious ID is the URL.
You would set CSSearchableItems UniqueIdentifier to the URL and NSUserActivity related to the unique identifier as well as the webpage URL to the URL.
if you use NSUserActivity and CoreSpotlight together, which is a very common pattern, you just want to ensure that they have the same ID.
Now this help search deduplicate results but it also helps items rank stronger.
Let's talk a bit about ranking.
The magic of search really is to provide the most relevant result based on a few keystrokes of input from the user.
We have done a lot of work here.
Relevance and ranking, is a complex function of matching the query to the items.
Most of this is completely transparent to you developers and to our users.
However, an important component of ranking is interaction with the content and results.
What you can do is help ensure that search can capture all of these interactions.
The three types of interactions that we care about, one is URL popularity, this is applicable to content that's indexed via web markup and this is based on any quality indications you add through schemas like ratings, likes, reviews, as well as the position of the URL in the web's link graph.
The URL improved this position based on popularity and this happens automatically.
The second interaction is the frequency of views that your content receives inside of the app.
Really the only way to capture this is through NSUserActivity which is why we encourage that you always adopt NSUserActivity.
The third and most important form of interaction is engagement with search results.
This is when a search result is presented to the user, whether they tap on the result, or if they're satisfied by the description in the result which we call silent engagement and we capture through session analytics.
A quick checklist of what to do to optimize relevance.
First, continue to do what you're doing, make great apps and great content.
Really, the search system is designed to find and bubble up the best content.
You can help by ensuring that we can capture all of the interactions, using NSUserActivity, use NSUserActivity with Public Indexing where applicable because now we can capture the engagements with your content across the user base.
Adopt schema mark-up for interactions counts and quality indications.
Finally follow user interface guidelines I'll talk about in a moment.
The flip side of bubbling up great content is suppressing content that is not relevant.
We have done a lot of work on this as well.
If malicious or a poorly considered app is spamming the index, we will downrank their results or suppress them entirely.
The most important sort of measure here is engagements-to-shown ratios, the amount of times your results are shown in search and how many times are engaged.
Low engagements will be suppressed and high engagement ratios will help your content rank up higher in search.
One of the best ways to get high engagements is to follow a few simple user guidelines.
One of the things you will notice in iOS 9 is search results even from built-in apps are very descriptive and rich and this is because we found that richer results get more engagements.
A few things here, provide a thumbnail, provide a well-structured readable description, ratings and actions where applicable.
The image in the thumbnail is really powerful, it gives the user a sense of what they'll see when they tap on the result.
Provide a good thumbnail.
Provide key information that the user is looking for.
For instance, if the user is looking for a booking number, a reference number, include it in the description so that the search task can be completed right there in search.
Now another powerful provision is support for keywords.
In all the APIs you can provide a number of keywords that will then trigger search results.
Category keywords tend to be very, very useful.
Users may search type "ticket" when searching for a specific ticket rather than typing the name, they may type "recipe" when looking for protein.
This creates a magical, intelligent experience for users.
Other types of keywords that are useful are synonyms and abbreviations, users want to type as little as possible, so instead of searching "San Francisco Giants" they may type "sf giants" and you can provide this recall through keywords.
Just as important, is behavior on launch.
This is what happens when the user taps on the result.
You want to take them straight to the content that they're looking for without interstitials, without pop-ups, without screens, without spending a lot of time loading that screen.
This is, in fact, so important that we measure and estimate the time from tap to the content shown and use it as a factor in ranking.
Here is two examples.
One is right.
One is wrong.
Let me show you what to do.
VIPUL PRAKASH: I'm sure none of you have apps that do that!
VIPUL PRAKASH: It is frustrating for the user and you want to find ways of completely avoiding it.
Let's talk about what to do next.
You can, of course, index your app content comprehensively, these are certain things that we have found to be very useful in the search context.
Any content that the user has viewed in the past that you can capture with NSUserActivity and content that the user may have created or curated by starring or creating lists inside of the app, people want to go back to things that they have done in the past.
Navigation points and features are very, very useful.
New messages, new content arriving that the user may want to look for inside of your app, you would also want to look for this in search.
You can get creative.
You can proactively index items that the user may want to look at.
Say I bought a ticket to a music festival, I may be interested in other music festivals in the area.
You can use your app analytics to figure out interesting content and put it in the index.
Really the APIs are flexible and allow you to create novel search experiences.
The possibilities here are really limitless.
So summary, just let's take a look of things we covered in the session.
We introduced fast on-device and cloud architecture that used for indexing deep links and for App Search.
We showed you three APIs and deep linking methods which you can adopt.
We showed you how great content, descriptive results, and fast content-to-result interaction can provide engaging search experience.
Provisions built in the APIs that are taking your content and showing it to iOS users around the world.
We have some more information.
If you're looking for details, you can head to our search API documentation portal, we have forums for more interactive help.
I'd recommend going to the session on seamless linking that Jason introduced.
We also have two labs, one that starts immediately after I stop talking.
You should come and join us there and another one on Friday and we would love to see some integrations with search APIs on Friday that you made during WWDC.
That's it for App Search.