Skip to content
View on GitHub

Find the location for an address, or places of interest near a location or within a specific area.

Screenshot for search with geocode sample

Use case

A user can input a raw address into the app's search bar and zoom to the address location. When getting directions or looking for nearby places, users may only know what the place has ("food"), the type of place ("gym"), or the generic place name ("Starbucks"), rather than the specific address. You can get suggestions and locations for these places of interest (POIs) using a natural language query. Additionally, you can filter the results to a specific area.

How to use the sample

Choose an address from the suggestions or submit your own address to show its location on the map in a callout. Tap on a result pin to display its address. If you pan away from the result area, a "Repeat Search Here" button will appear. Tap it to query again for the currently viewed area on the map.

How it works

  1. Create a LocatorSearchSource using the toolkit.
  2. Create a SearchView using the toolkit with the locator search source.
  3. Perform a search. Identify a result pin graphic in the graphics overlay and show a callout with its address.

Relevant API

  • ArcGISToolkit.LocatorSearchSource
  • ArcGISToolkit.SearchView
  • GeocodeParameters
  • LocatorTask
  • SearchResult
  • SearchSuggestion
  • SuggestParameters

Additional information

This sample uses the World Geocoding Service. For more information, see Geocoding service from Esri Developer website.

Tags

address, businesses, geocode, locations, locator, places of interest, POI, point of interest, search, suggestions, toolkit

Sample Code

SearchWithGeocodeView.swift
Use dark colors for code blocksCopy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 // Copyright 2022 Esri // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License.  import ArcGIS import ArcGISToolkit import SwiftUI  struct SearchWithGeocodeView: View {  /// The viewpoint used by the search view to pan/zoom the map to the extent  /// of the search results.  @State private var viewpoint: Viewpoint? = Viewpoint(  center: Point(  x: -93.258133,  y: 44.986656,  spatialReference: .wgs84  ),  scale: 1e6  )   /// Denotes whether the map view is navigating. Used for the repeat search  /// behavior.  @State private var isGeoViewNavigating = false   /// The current map view extent. Used to allow repeat searches after  /// panning/zooming the map.  @State private var geoViewExtent: Envelope?   /// The center for the search.  @State private var queryCenter: Point?   /// The screen point to perform an identify operation.  @State private var identifyScreenPoint: CGPoint?   /// The tap location to perform an identify operation.  @State private var identifyTapLocation: Point?   /// The placement for a graphic callout.  @State private var calloutPlacement: CalloutPlacement?   /// Provides search behavior customization.  @StateObject private var locatorDataSource = LocatorSearchSource(  name: "My Locator",  maximumResults: 10,  maximumSuggestions: 5  )   /// The view model for the sample.  @StateObject private var model = Model()   var body: some View {  MapViewReader { proxy in  MapView(  map: model.map,  viewpoint: viewpoint,  graphicsOverlays: [model.searchResultsOverlay]  )  .onSingleTapGesture { screenPoint, tapLocation in  identifyScreenPoint = screenPoint  identifyTapLocation = tapLocation  }  .onNavigatingChanged { isGeoViewNavigating = $0 }  .onViewpointChanged(kind: .centerAndScale) {  queryCenter = $0.targetGeometry.extent.center  }  .onVisibleAreaChanged { newVisibleArea in  // For "Repeat Search Here" behavior, use `geoViewExtent` and  // `isGeoViewNavigating` modifiers on the search view.  geoViewExtent = newVisibleArea.extent  }  .callout(placement: $calloutPlacement.animation()) { placement in  // Show the address of user tapped location graphic.  // To get the fully geocoded address, use "Place_addr".  Text(placement.geoElement?.attributes["Match_addr"] as? String ?? "Unknown Address")  .padding()  }  .task(id: identifyScreenPoint) {  guard let screenPoint = identifyScreenPoint,  // Identifies when user taps a graphic.  let identifyResult = try? await proxy.identify(  on: model.searchResultsOverlay,  screenPoint: screenPoint,  tolerance: 10  )  else {  return  }  // Creates a callout placement at the user tapped location.  calloutPlacement = identifyResult.graphics.first.flatMap { graphic in  CalloutPlacement.geoElement(graphic, tapLocation: identifyTapLocation)  }  identifyScreenPoint = nil  identifyTapLocation = nil  }  .overlay {  SearchView(  sources: [locatorDataSource],  viewpoint: $viewpoint  )  .resultsOverlay(model.searchResultsOverlay)  .queryCenter($queryCenter)  .geoViewExtent($geoViewExtent)  .isGeoViewNavigating($isGeoViewNavigating)  .onQueryChanged { query in  if query.isEmpty {  // Hides the callout when query is cleared.  calloutPlacement = nil  }  }  .padding()  }  }  } }  private extension SearchWithGeocodeView {  /// The model used to store the geo model and other expensive objects  /// used in this view.  class Model: ObservableObject {  /// A map with imagery basemap.  let map = Map(basemapStyle: .arcGISImagery)   /// The graphics overlay used by the search toolkit component to display  /// search results on the map.  let searchResultsOverlay = GraphicsOverlay()  } }  #Preview {  SearchWithGeocodeView() }

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.