All docschevron-rightNavigation SDK for iOSchevron-rightGuideschevron-rightarrow-leftAdvancedchevron-rightSearch SDK Integration

Search SDK Integration

The Mapbox Search SDK provides the tools to add a search experience to your navigation application. Integrating the Search SDK with your application allows users to search for locations by place name, address, category, or coordinate. It also allows access to search history and save searches as Favorites.

To integrate the Search SDK into your application, you can provide search programmatically. Use your own UI implementation with the search API from MapboxSearch package for higher customization and flexibility.

Before starting to integrate your application with the Search SDK, you’ll need to add the Search SDK as a dependency. Mapbox provides the Search SDK via CocoaPods and Swift Package Manager (SPM), but SPM is the recommended method for integrating the Search SDK. To install, follow the steps for adding the Search SDK as a dependency to your application. The secret access token with Downloads:Read scope that you use for your Navigation SDK application will work.

troubleshooting
Running into problems installing?

The Navigation SDK and Search SDK share two dependencies. If the package manager fails to install the dependencies, check that the versions of the Navigation SDK and Search SDK have compatible versions of MapboxCommon and MapboxMobileEvents. Read more about version compatibility issues in our troubleshooting guide.

chevron-right

Integrating with the Search SDK

For the simplicity and speed of the Search SDK integration, we provide a ready-to-use search panel SearchPanel, but if you want higher customization and flexibility, you can use the Search API without predefined UI. For both options, there are a few things you will still need to make sure the Search SDK can interact with the Navigation SDK application.

Send a search result to the Navigation SDK

A Search SDK selected query will return a SearchResult for the user's desired destination. A SearchResult is a search object with populated fields such as its result name, description, coordinates, and RoutablePoints that will allow you to display search results on the map as well as navigate to a desired result. After you retrieve a SearchResult, you will need to send it to the Navigation SDK to navigate to the desired result.

Here is an example of handling a search result selection:

func handleSearchResultSelection(_ searchResult: SearchResult) {
    let coordinate = routablePoints?.first?.point ?? searchResult.coordinate
    let destinationWaypoint = Waypoint(coordinate: coordinate, name: "\(searchResult.name)")
    destinationWaypoint.targetCoordinate = coordinate
    let navigationRouteOptions = NavigationRouteOptions(waypoints: [userWaypoint, destinationWaypoint])
    Directions.calculateRoutes(navigationRouteOptions) { [weak self (session, result) in
        switch result {
        case .failure(let error):
            print(error)
        case .success(let response):
            // Handle RouteResponse
        }
    }
}

When implementing, hand the retrieved SearchResult itself to the Navigation SDK instead of using its coordinate or RoutablePoints individually. searchResult.coordinate provides the center coordinates of a search result while searchResult.routablePoints provides coordinates that correspond to a building's entrance. Not all search results will include RoutablePoints, but when included in the result you should use them to navigate the user to their destination. The sample code above does this here:let coordinate = searchResult.routablePoints?.first?.point ?? searchResult.coordinateTo set this coordinate as a destination for your user, create a Waypoint with the coordinate and pass it as the destination waypoint. When requesting a route from the Directions API and using this RoutablePoint as a destination, the returned route will snap to the road and originate from the optimal direction. To further optimize the user experience you can set the Waypoint.targetCoordinate to the building centerpoint and -- if you want your user to arrive curbside -- set Waypoint.allowsArrivingOnOppositeSide.

If you choose to display search results as annotations on the map, make sure to remove the results before displaying the route.

Send coordinates from the Navigation SDK to the Search SDK

You can use the Search SDK's SearchEngine class to do reverse geocoding which allows users to search for place names and addresses by providing geographic coordinates. For example, the user can tap the map to find places nearby or see places near their destination.

If you want to tap on the map and display places nearby, you can add a new gesture like this:

func handleMapTapped(_ gesture: UITapGestureRecognizer) {
    guard gesture.state == .ended else { return }
    let coordinate = navigationMapView.mapView.mapboxMap.coordinate(for: gesture.location(in: navigationMapView.mapView))
    let searchOptions = ReverseGeocodingOptions(point: coordinate)
    searchEngine.reverseGeocode(options: searchOptions) { geocodingResult in
        switch geocodingResult {
        case .success(let searchResults):
            // Display search results
            let annotations = searchResults.map { searchResult -> PointAnnotation in
                var annotation = PointAnnotation(coordinate: searchResult.coordinate)
                annotation.textField = searchResult.name
                return annotation
            }
            pointAnnotationManager?.annotations = annotations
        case .failure(let searchError):
            return
        }
    }
}

PointAnnotationManager is used to manage PointAnnotations and is exposed as a property in NavigationMapView.pointAnnotationManager.

Remember to set up the tap gesture recognizer by adding it to the NavigationMapView.

Add autocomplete search view to the navigation view

Besides displaying a user's favorites and search history, you can also add autocomplete search view that suggests queries based on the input text using a custom search box. Incorporating autocomplete enhances the search experience by allowing the user to click on the desired result before finishing the query. As the user types in the query, results update in real time and your application receives updates as SearchSuggestions through the SearchEngineDelegate protocol.

searchEngine.query = textField.text!

extension ViewController: SearchEngineDelegate {
    func suggestionsUpdated(suggestions: [SearchSuggestion], searchEngine: SearchEngine) {
        // Handle suggestions
    }
}

A SearchSuggestion contains only enough information to display the suggestion in a list. To get a coordinate or detailed address information for navigation, pass the suggestion back to the SearchEngine.select(suggestion:) method in response to a user selection.

Additional notes

Pricing for the Navigation SDK and Search SDK are calculated separately. For pricing information for the Search SDK, see the pricing guide.

Was this page helpful?