← Files MapboxARCHIVED FILE
skills/mapbox-search-integration/references/ios-search.md
4.08 KB · Sep 30, 2026 · 23:11 UTC
# iOS: Search SDK for iOS
## Option 1: Search SDK with UI (Easiest)
**When to use:** iOS app, want pre-built search UI, fastest implementation
**Installation:**
Stable Search SDK releases do not require a secret download token or `~/.netrc`. Add a public token (`pk.*`) as `MBXAccessToken` in `Info.plist`.
```swift
// Add to Package.swift or SPM
dependencies: [
.package(url: "https://github.com/mapbox/mapbox-search-ios.git", from: "2.0.0")
]
```
**Complete implementation with built-in UI:**
```swift
import MapboxSearch
import MapboxMaps
class SearchViewController: UIViewController {
private var searchController: MapboxSearchController!
private var mapView: MapView!
override func viewDidLoad() {
super.viewDidLoad()
setupMap()
setupSearchWithUI()
}
func setupMap() {
mapView = MapView(frame: view.bounds)
view.addSubview(mapView)
}
func setupSearchWithUI() {
// MapboxSearchController provides complete UI automatically
searchController = MapboxSearchController()
searchController.delegate = self
// Present the search UI
present(searchController, animated: true)
}
}
extension SearchViewController: SearchControllerDelegate {
func searchResultSelected(_ searchResult: SearchResult) {
// SDK handled all the search interaction
// Just respond to selection
mapView.camera.fly(to: CameraOptions(
center: searchResult.coordinate,
zoom: 15
))
let annotation = PointAnnotation(coordinate: searchResult.coordinate)
mapView.annotations.pointAnnotations = [annotation]
dismiss(animated: true)
}
}
```
## Option 2: Search SDK Core (Custom UI)
**When to use:** Need custom UI, integrate with UISearchController, full control over UX
**Complete implementation:**
```swift
import MapboxSearch
import MapboxMaps
class SearchViewController: UIViewController {
private var searchEngine: SearchEngine!
private var mapView: MapView!
override func viewDidLoad() {
super.viewDidLoad()
// Initialize Search Engine (SDK handles debouncing and session tokens)
searchEngine = SearchEngine(accessToken: "YOUR_MAPBOX_TOKEN")
setupSearchBar()
setupMap()
}
func setupSearchBar() {
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
navigationItem.searchController = searchController
}
func setupMap() {
mapView = MapView(frame: view.bounds)
view.addSubview(mapView)
}
}
extension SearchViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
guard let query = searchController.searchBar.text, !query.isEmpty else {
return
}
// Search SDK handles debouncing automatically
searchEngine.search(query: query) { [weak self] result in
switch result {
case .success(let results):
self?.displayResults(results)
case .failure(let error):
print("Search error: \(error)")
}
}
}
func displayResults(_ results: [SearchResult]) {
// Display results in custom table view
// When user selects a result:
handleResultSelection(results[0])
}
func handleResultSelection(_ result: SearchResult) {
mapView.camera.fly(to: CameraOptions(
center: result.coordinate,
zoom: 15
))
let annotation = PointAnnotation(coordinate: result.coordinate)
mapView.annotations.pointAnnotations = [annotation]
}
}
```
## Option 3: Direct API Integration (Advanced)
**When to use:** Very specific requirements, server-side iOS backend
**Important:** Only use if SDK doesn't meet your needs. You must handle debouncing and session tokens manually.
```swift
// Direct API calls - see Web direct API example
// Not recommended for iOS - use Search SDK instead
```
SHA-256: 3b8ca36a2f920bb9ef757c8b259dc2b84c41724ee3e542fc5bec50122de9b1fd