iOS 9 App Search Tutorial: Introduction to App Search
Discover how easy it is to make your app’s content searchable through Spotlight with this iOS 9 app search tutorial. By Chris Wagner.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
iOS 9 App Search Tutorial: Introduction to App Search
25 mins
Opening search results
The ideal user experience is to launch the app directly to the relevant content without any fanfare. In fact — it’s a requirement — Apple uses the speed at which your app launches and displays useful information as one of the metrics to rank search results.
In the previous section, you laid the groundwork for this by providing both an activityType
and a userInfo
object for your NSUserActivity
instances.
Open AppDelegate.swift and add this empty implementation of application(_:continueUserActivity:restorationHandler:)
below application(_:didFinishLaunchingWithOptions:)
:
func application(application: UIApplication,
continueUserActivity userActivity: NSUserActivity,
restorationHandler: ([AnyObject]?) -> Void) -> Bool {
return true
}
When a user selects a search result, this method is called — it’s the same method that’s called by Handoff to continue an activity from another device.
Add the following logic above return true
in application(_:continueUserActivity:restorationHandler:)
:
guard userActivity.activityType == Employee.domainIdentifier,
let objectId = userActivity.userInfo?["id"] as? String else {
return false
}
This guard
statement verifies the activityType
is what you defined as an activity for Employees, and then it attempts to extract the id
from userInfo
. If either of these fail, then the method returns false
, letting the system know that the activity was not handled.
Next, below the guard
statement, replace return true
with the following:
if let nav = window?.rootViewController as? UINavigationController,
listVC = nav.viewControllers.first as? EmployeeListViewController,
employee = EmployeeService().employeeWithObjectId(objectId) {
nav.popToRootViewControllerAnimated(false)
let employeeViewController = listVC
.storyboard?
.instantiateViewControllerWithIdentifier("EmployeeView") as!
EmployeeViewController
employeeViewController.employee = employee
nav.pushViewController(employeeViewController, animated: false)
return true
}
return false
If the id
is obtained, your objective is to display the EmployeeViewController
for the matching Employee.
The code above may appear a bit confusing, but think about the app’s design. There are two view controllers, one is the list of employees and the other shows employee details. The above code pops the application’s navigation stack back to the list and then pushes to the specific employee’s details view.
If for some reason the view cannot be presented, the method returns false
.
Okay, time to build and run! Select Cary Iowa from the employees list, and then go to the home screen. Activate Spotlight and search for Brent Reid. When the search result appears, tap it. The app will open and you’ll see it fade delightfully from Cary to Brent. Excellent work!
Deleting items from the search index
Back to the premise of your app. Imagine that an employee was fired for duct taping the boss to the wall after a particularly rough day. Obviously, you won’t contact that person anymore, so you need to remove him and anybody else that leaves the company from the Colleagues search index.
For this sample app, you’ll simply delete the entire index when the app’s indexing setting is disabled.
Open EmployeeService.swift and add the following import statement at the top of the file.
import CoreSpotlight
Next, find destroyEmployeeIndexing()
. Replace the TODO
with the following logic:
CSSearchableIndex
.defaultSearchableIndex()
.deleteAllSearchableItemsWithCompletionHandler { error in
if let error = error {
print("Error deleting searching employee items: \(error)")
} else {
print("Employees indexing deleted.")
}
}
This single parameterless call destroys the entire indexed database for your app. Well played!
Now to test out the logic; perform the following test to see if index deletion works as intended:
- Build and run to install the app.
- Stop the process in Xcode.
- In the simulator or on your device, go to Settings \ Colleagues and set Indexing to Viewed Records.
- Open the app again and select a few employees so that they are indexed.
- Go back to the home screen and activate Spotlight.
- Search for one of the employees you viewed and verify the entry appears.
- Go to Settings \ Colleagues and set Indexing to Disabled.
- Quit the app.
- Reopen the app. This will purge the search index.
- Go to the home screen and activate Spotlight.
- Search for one of the employees you viewed and verify that no results appear for the Colleagues app.
So deleting the entire search index was pretty easy, huh? But what if you want to single out a specific item? Good news — these two APIs give you more fine-tuned control over what is deleted:
-
deleteSearchableItemsWithDomainIdentifiers(_:completionHandler:)
lets you delete entire “groups” of indexes based on their domain identifiers. -
deleteSearchableItemsWithIdentifiers(_:completionHandler:)
allows you work with individual records using their unique identifiers.
This means that globally unique identifiers (within an app group) are required if you’re indexing multiple types of records.
If you’ve run into any issues you can download the completed project here.
Where to go from here?
This iOS 9 app search tutorial has covered iOS 9’s simple yet powerful approach to indexing the content inside your app using user activities. Searching isn’t limited to content though — you can also use it to index navigation points within an app.
Consider a CRM app that has multiple sections such as Contacts, Orders and Tasks. By creating user activities whenever a user lands on one of these screens, you’d make it possible for them to search for Orders and be directly to that section of your app. How powerful would this be if your app has many levels of navigation?
There are many unique ways to bubble up content to your users. Think outside the box and remember to educate your users about this powerful function.
This tutorial was an abbreviated version of Chapter 2, “Introducing App Search” from iOS 9 by Tutorials. If you’d like to learn about indexing large data sets with Core Spotlight or web content with iOS 9 please check out the book!