The Search API (i.e MKLocalSearch
) allows iOS developers to search for points of interest and display them on maps. App developers can use this API to perform searches for locations, which can be name, address, or type, such as coffee or pizza.
The use of MKLocalSearch
is very similar to the MKDirections
API covered in the previous chapter. You'll first need to create an MKLocalSearchRequest
object that bundles your search query. You can also specify the map region to narrow down the search result. You then use the configured object to initialize an MKLocalSearch
object and perform the search.
The search is performed remotely in an asynchronous way. Once Apple returns the search result (as an MKLocalSearchResponse
object) to your app, the complete handler will be executed. In general, you'll need to parse the response object and display the search results on the map.
There is no better way to understand local search than working on a demo project. Again we will not start from scratch but build on top of the previous project to add a Nearby feature. When you tap the Nearby button, the app searches for nearby restaurants and pins the places on the map.
To start with, first download the Xcode project template from http://www.appcoda.com/resources/swift55/LocalSearchStarter.zip. Unzip it and open the MapKitDirection
project.
Note: The starter project is exactly the same as the final project of the MapKit Direction demo.
Okay, let's get started. First, go to Main
storyboard and add a button item to the map view. Set the image of the button to face.smiling. After that, add the spacing and size constraints. When tapped, this button will show the nearby restaurants. From now and onwards, I refer this button as the Nearby button.
Once you added the button, open the MapViewController.swift
file. We will create an action method called showNearby
for the Nearby button. In the implementation, we will search for nearby restaurants and pin the results on the map.
Insert the following code snippet in the class:
@IBAction func showNearby(sender: UIButton) {
let searchRequest = MKLocalSearch.Request()
searchRequest.naturalLanguageQuery = restaurant.type
searchRequest.region = mapView.region
let localSearch = MKLocalSearch(request: searchRequest)
localSearch.start { (response, error) -> Void in
guard let response = response else {
if let error = error {
print(error)
}
return
}
let mapItems = response.mapItems
var nearbyAnnotations: [MKAnnotation] = []
if mapItems.count > 0 {
for item in mapItems {
// Add annotation
let annotation = MKPointAnnotation()
annotation.title = item.name
annotation.subtitle = item.phoneNumber
if let location = item.placemark.location {
annotation.coordinate = location.coordinate
}
nearbyAnnotations.append(annotation)
}
}
self.mapView.showAnnotations(nearbyAnnotations, animated: true)
}
}
To perform a local search, here are the two things you need to do:
MKLocalSearch.Request
object. You are allowed to specify the search criteria in natural language by using the naturalLanguageQuery
parameter. For example, if you want to search for a nearby cafe, you can specify cafe in the search parameter. Since we want to search for similar types of restaurants, we specify restaurant.type
in the query. MKLocalSearch
object with the search parameters. An MKLocalSearch
object is used to initiate a map-based search operation and delivers the results back to your app asynchronously.In the showNearby
method, we lookup the nearby restaurants that are of the same type (e.g. Italian). Furthermore, we specify the current region of the map view as the search region.
We then initialize the search by creating the MKLocalSearch
object and invoking the start(completionHandler:)
method. When the search completes, the closure will be called and the results are delivered as an array of MKMapItem
. In the body of the closure, we loop through the items (i.e. nearby restaurants) and highlight them on the map using annotations. To pin multiple annotations on maps, you call the showAnnotations
method and pass it the array of MKAnnotation
objects to pin.
Okay, you're almost ready to test the app. Just go to the storyboard and connect the Nearby button with the showNearby
method. Simply control-drag from the Nearby button to the view controller icon in the scene dock and select the showNearbyWithSender:
action method.
Now hit the Run button to compile and run your app. Select a restaurant to bring up the map view. Tap the Nearby button and the app should show you the nearby restaurants.
Cool, right? With just a few lines of code, you took your Map app to the next level. If you're going to embed a map within your app, try to explore the local search API.
For reference, you can download the complete Xcode project from http://www.appcoda.com/resources/swift55/LocalSearch.zip.