WWDC 2015

Introducing Search APIs

User spends more time on apps than web

  • developers select what to index
  • app result shows in Spotlight and Safari
  • app result shows even the app is not installed

How Apple discover the app content

  • Deep Links go into Apple cloud index as well
  • Developer tag the content as public
  • Apple find deep links from the web as the web mirror the contents of app
  • appear in iOS 9 search

NSUserActivity

NSUserActivity used primary in Handoff which introduced in iOS 8.

In iOS 9, activities can be designed as searchable.

Steps to add into on-device index

  1. Create NSUserActivity
  2. Added related metadata such as the title, descriptions and thumbnails
  3. Add that activity to the index

the following properties are only available in iOS 9

setting eligibleForHandoff to true that allows that activity can be continues via Hand off

setting eligibleForSearch to true that allows that activity can be as a result in Spotlight

setting keywords with keywords for helping the search

setting contentAttrivuteSet for information appearing in search result

setting expirationDate for the date of expiring any content when the content is not valid in after the expiration date.


setting webpageURL for restoration to a web page

Creating NSUserActivity

var activity: NSUserActivity = NSUserActivity(activityType:"com.myApp.myActivity")
activity.title = "activity title"
activity.userInfo = ["id": "1234"]
activity.eligibleForSearch = true
activity.becomeCurrent()

the search result

Receiving NSUserActivity ( same from search results and hand off)

func application(UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: [AnyObject]? -> Void) -> Bool {

    //handle the activity
    if userActivity.activityType == "com.myApp.myActivity" {

    } 

    return true
}

Designating Activities Public

var activity: NSUserActivity = NSUserActivity(activityType:"com.myApp.myActivity")
activity.title = "activity title"
activity.userInfo = ["id": "1234"]
activity.eligibleForSearch = true
//setting the public indexing as true
activity.eligibleForPublicIndexing = true
activity.becomeCurrent()
  • Activities are private as default
  • only pulic of those activities marked as public
  • threshold of indexing (i.e. CloudIndex would only index the activities after a number of same user activities have been done.)

Addditional Benefits

  • adopting hand off
  • Siri suggestion and smart reminders

CoreSpotlight

  • treated as database
  • index for all app content
  • create, update and delete
  • adopt by Message, Mail, Calendar and Notes

Steps to create

  1. Create CSSearchableItemAttributeSet
  2. Create CSSearcableItem
  3. Add them to index
let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUUTypeImage as String)

attributeSet.title = "Sunrise"
attributeSet.contentDescription = "Nice Sunrise on May 12, 2015"

//Create item with unique id, domainIdentifier for groupping up the the items 
let item = CSSearchableItem(uniqueIdentifier: "1", domainIdentifier : "album-1", attributeSet: attributeSet)

CSSearchableIndex.defaultSearchableIndex().indexSearchableItems([Item]) { error in
    if error != nil {
        //handle error
    } else {
        //index success
    }
}

Restoration

Same API as hand off but the type checked against is CSSearchableItemActionType

func application(UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: [AnyObject]? -> Void) -> Bool {

    //handle the search result
    if userActivity.activityType == CSSearchableItemActionType {

        let uniqueIdentifier = userActivity.userInfo?[CSSearchableItemActivityIdentifier] as? String

    } 

    return true
}

Update

same method as adding item to index

func indexSearchableItems(items: [CSSearchableItem], completionHandler:
((NSError?) -> Void)?)

Delete

delete items by identifiers

func deleteSearchableItemsWithIdentifiers(identifiers: [String],
completionHandler: ((NSError?) -> Void)?)

by domain identifiers

func deleteSearchableItemsWithDomainIdentifiers(domainIdentifiers: [String],
completionHandler: ((NSError?) -> Void)?)

or all

func deleteAllSearchableItemsWithCompletionHandler(completionHandler: ((NSError?) -> Void)?)

Additional features

  • item size can be large so the index allows batching
  • CSSearchableIndexDelegate for observe any indexing changes
  • extension
  • Data protection class for more security features

Web markup

As some of the website mirrors the conten of the app. Search in iOS 9 can also shows the results from those websites.

Enable app search

  1. Allow Apple to discover and index the website
  2. the website contains markup for mobile deeplinks
  3. have deep link handling for the app
  4. Add markup for structured data (not required but recommended)

Smart app banner

Showing the app banner promotion on the top of the website

Prepare the website

Related session: seamless linking to your app

Added twitter cards and Facebook App links as well

Rich results

Besides showing title and description, images or other media can also used for search results.

Rating, offer, price ranges, interaction counts, organization and recipe

Phone number, directions or playing audio or video are actionable for iOS search results.

check below for more info

Resources Link
App Search Developer Site http://developer.apple.com/ios/search/
Twitter’s Cards Protocol http://dev.twitter.com/cards/mobile
Facebook’s App Links http://applinks.org
schema.org http://schema.org
Open Graph http://ogp.me

Relevance: Linking APIs

NSUserActivity.relatedUniqueIndentifer should same as CSSearchableItem.uniqueIdentifier

  • provide the most relevant results
  • result quality related to the user interaction
  • three thing contributed to relevance score
    • URL popularity
    • User Activity
    • Engagement (how many user tap the result)

Boosting the ranking

  • create great app and content
  • adopting API to gives most relevance
    • NSUserActivity
    • NSUserActivity public indexing as needed.
    • Schema markup for rating and reviews
  • Follow UI guideslines
    • when the user search a result, there should be no interruption to that result of you app
    • Go straign to the content , no full screen and multi-steps or requiring user login
    • applies to web and app as well
    • Time from result to content is a one of factor of ranking.

Protecting Relevance

  • down-rank or suppress poor results
  • Malicious or poorly considered implementation will be penalized
  • Ratio of engagement-to-shown is a key metric
    • Results
      • Rich results have thumbnails and well-organized data, ratings and actions
      • Relevant and appealing image
      • key information is user looking for
    • Keywords
      • 3 - 5 words
      • category "tickets" or recipe" helps
      • Synonyms and abbreviations for item subject

What to index

  • content viewed, created and curated by user
  • Navigation points and features
  • New message, content and items arriving on device
  • proactively indexed items as potential interest
  • iOS Search is flexible, extensible, and open to creativity