CoreSpotlight: What data to index and which approach is best?

I work on a sports app, and we'd like our users to be able to use spotlight to search for teams, players and leagues. When they tap on a search result it will open the app the relevant screen. We already support this mode of entry via push notifications, url schemes, etc so the mapping of identifier to screen isn't a problem.


What I'm wondering is how to best go about adding all of our content to Spotlight's index.


I've made a sample app that fetches each team in the app on first launch and creates a CSSearchableItem for it. This works fine, but I have a few concerns:


  1. We have hundreds of teams, and thousands of players. Is this the appropriate kind of content to be indexed?
  2. Is this brute-force populating of the search index appropriate, or will it have performance implications?
  3. Should we be using NSUserActivity instead? We use them already for handoff, but am I correct in thinking that each NSUserActivity will only be indexed when the screen is first visited?
  4. We have a public website that maps pages for each team/league/etc to screens in our app, will having the site opt in to the web crawler APIs be enough?


Thanks!

Accepted Answer

These are all really good questions. I think you're pretty squarely in the camp of wanting to use all 3 APIs we described in the WWDC session. They are definitely complementary, and most developers will want to use multiple in conjunction with each other.


Since you have public website content I'd recommend that you add web markup information there and ensure that Applebot can access the content (making sure it's available via the URLs you specify in iTunes Connect is one good way of doing this). You'll want to also make sure you're using a Smart App Banner with a deep link to your app on any pages that your app can show. Since you already handle these entries into your app this should be easy for you. Just make sure you're specifying the app-argument in the content value to a deep link into your content. More generally, you'll want to support Univeral Links as the way you get users into your app, and also for the things like the webpageURL on NSUserActivities, and for identifiers of your CSSearchableItem objects.


You should definitely be using NSUserActivity to indicate which activities are searchable, and more importantly which activities are publicly indexable. By doing this, and making sure you specify the appropriate webpageURL, we can get more meaningful information about the contents in our public index. If we see multiple users actively interacting with your content then we can adjust the rankings since we know that it's more relevant to users. One way of thinking about this is that the web markup gets your content into the public index, and NSUserActivity adds relevance information on top of this.


You still might want to use CoreSpotlight directly to add items to the private local index so that it's directly searchable and doesn't rely on the public index. If your users have the ability to indicate their favorite teams or players, or if they participate in fantasy leagues, you should add the relevant player/team information directly to the spotlight index. If your app has messaging capabilities, that's another great example of what to put into Spotlight. More broadly, you'd want to use spotlight for any user-generated content (e.g. messages) or user-specific content (e.g. favorites lists). Again, be sure to use your website's URLs as the identifiers, so that we can correlate things between the different entrypoints.


I hope this helps clarify a little bit how you can be approaching this new feature. Definitely continue asking questions as it will benefit other folks participating or lurking in the forums.

Sorry for hi-jacking this thread, but your reply leads to some questions:

You'll want to also make sure you're using a Smart App Banner with a deep link to your app on any pages that your app can show. Since you already handle these entries into your app this should be easy for you. Just make sure you're specifying the app-argument in the content value to a deep link into your content. More generally, you'll want to support Univeral Links as the way you get users into your app, and also for the things like the webpageURL on NSUserActivities, and for identifiers of your CSSearchableItem objects.


Question:

Given I have web content at "mydomain.com/content-my-app-understands" and I have a Smart App Banner there with

<meta name="apple-itunes-app" content="app-id=myAppStoreID, app-argument=myURL_telling_the_app_what_to_show">

where "myURL_telling_the_app_what_to_show" is a URL with custom URL scheme like

myAppName://show-this-with-id


When this page gets crawled, spotlight puts it in its global index and the user taps a spotlight search result: In which property of the resulting NSUserActivity of

- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
 restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler

will be the app-argument of the Smart App Banner? Or does the app still gets openend via

- (BOOL)application:(UIApplication *)application            
openURL:(NSURL *)url  
sourceApplication:(NSString *)sourceApplication       
  annotation:(id)annotation


Or does the app need to know the corresponding webURL (which would make the custom app-argument of no use, because the app would have to understand the content the webURL property)?

Thanks for the detailed response.


A few follow-up questions:

  1. NSUserActivity is just for places in the app that the user has visited, e.g. the SF Giants page, and not for proactively indexing all possible states of the app, e.g. every team in the MLB?
  2. CoreSpotlight should be used for user-generated content
  3. Content that is correlated with a web site should be indexed via the web API.


My concern is that a user will open up spotlight on their iOS device and search for a team and not see our app in the search results because they haven't visited that team's page in the app.


Is the correct approach to hope that enough users visit that team's page in the app (and thus its NSUserActivity) that the correlated web index will surface our app/site in the spotlight search?


Thanks!

This came up in another thread. When Smart App Banner items are opened by way of the search results, they'll come in via the Handoff API.

1. Correct, NSUserActivity should be used in response to exactly that, user activity.


2 and 3. Core Spotlight should definitely be used for user-generated content, but it can also be used for other things like lists of favorites or recent items the user has used. It doesn't strictly have to be "user-generated" content. For content that might also be on the web you could index that with Core Spotlight since the user may, as you describe, want to search for it explicitly and it may not have been crawled. Does that make sense?


When it comes to public activities, yes, the idea is that as more user activities get seen (assuming they're marked eligibleForPublicIndexing = true) then that will raise the ranking of those search results.

Thanks for the response, but this does not answer the question completely: given I come into the app via

- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler


How to read the deeplink URL from the userActivity?


Also: How to actually test that?

It would be in the userActivity.webpageURL property.

So in the webpageURL would be aURL of kind

myAppName://show-this-with-id

???

That doew not make any sense as the documentation of webpageURL states:


The scheme of the webpageURL must be http or https. Any other scheme throws an exception.


So to repeat:

  1. I have an app which understands a custom URL scheme
  2. I have SmartAppBanners with the custom URL scheme in its app-argument
  3. The AppleBot crawls my site at e.g. "mydomain.com/content-my-app-understands"


So my question again: How to access my original deeplink ("myAppName://show-this-with-id") from the NSUserActivity when the user presses a search result?

CoreSpotlight: What data to index and which approach is best?
 
 
Q