Skip to content
View on GitHub

Use an online service to find the address for a tapped point.

Image of find address with reverse geocode

Use case

You might use a geocoder to find a customer's delivery address based on the location returned by their device's GPS.

How to use the sample

Tap the map to see the nearest address displayed in a callout.

How it works

  1. Create a LocatorTask object using a URL to a geocoder service.
  2. Create an instance of ReverseGeocodeParameters and set ReverseGeocodeParameters.maxResults to 1.
  3. Pass the ReverseGeocodeParameters into LocatorTask.reverseGeocode(forLocation:parameters:) and get the matching results from the GeocodeResult.
  4. Show the results using a PictureMarkerSymbol and add the symbol to a Graphic in the GraphicsOverlay.

Relevant API

  • GeocodeResult
  • LocatorTask
  • ReverseGeocodeParameters

Additional information

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

Tags

address, geocode, locate, reverse geocode, search

Sample Code

FindAddressWithReverseGeocodeView.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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 // Copyright 2023 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 SwiftUI  struct FindAddressWithReverseGeocodeView: View {  /// The view model for the sample.  @StateObject private var model = Model()   /// The point on the map where the user tapped.  @State private var tapLocation: Point?   /// The placement of the callout on the map.  @State private var calloutPlacement: CalloutPlacement?   /// The text shown in the callout.  @State private var calloutText: String?   /// The error shown in the error alert.  @State private var error: Error?   var body: some View {  MapView(map: model.map, graphicsOverlays: [model.graphicsOverlay])  .callout(placement: $calloutPlacement.animation(.default.speed(2))) { _ in  Text(calloutText ?? "No address found.")  .font(.callout)  .padding(8)  }  .onSingleTapGesture { _, mapPoint in  tapLocation = mapPoint  }  .task(id: tapLocation) {  guard let tapLocation else { return }  await reverseGeocode(tapLocation)  }  .task {  do {  try await model.locatorTask.load()  } catch {  self.error = error  }  }  .overlay(alignment: .top) {  Text("Tap on the map to get the address for point.")  .frame(maxWidth: .infinity, alignment: .center)  .padding(8)  .background(.thinMaterial, ignoresSafeAreaEdges: .horizontal)  }  .errorAlert(presentingError: $error)  }   /// Reverse geocodes a given point and updates the marker with the result.  /// - Parameter mapPoint: The point on the map to reverse geocode.  private func reverseGeocode(_ mapPoint: Point) async {  // Normalize the map point.  guard let normalizedPoint = GeometryEngine.normalizeCentralMeridian(  of: mapPoint  ) as? Point else { return }   do {  // Perform reverse geocode using the locator task with the point and parameters.  let geocodeResults = try await model.locatorTask.reverseGeocode(  forLocation: normalizedPoint,  parameters: model.reverseGeocodeParameters  )   // Update the callout text using the first result from the reverse geocode.  updateCalloutText(using: geocodeResults.first)  } catch {  self.error = error  calloutText = nil  }   // Update the marker and callout location.  model.markerGraphic.geometry = normalizedPoint  calloutPlacement = .geoElement(model.markerGraphic, tapLocation: normalizedPoint)  }   /// Updates the callout text using the address from a given geocode result.  /// - Parameter geocodeResult: The result to get the address from.  private func updateCalloutText(using geocodeResult: GeocodeResult?) {  // Get the address from the result's attributes.  let addressText = model.reverseGeocodeParameters.resultAttributeNames  .compactMap { geocodeResult?.attributes[$0] as? String }  .filter { !$0.isEmpty }  .joined(separator: ", ")   // Update the callout text if an address was found.  calloutText = !addressText.isEmpty ? addressText : nil  } }  private extension FindAddressWithReverseGeocodeView {  /// The model used to store the geo model and other expensive objects used in this view.  class Model: ObservableObject {  /// A map with a topographic basemap initially centered on Redlands, CA, USA.  let map = {  let map = Map(basemapStyle: .arcGISTopographic)  map.initialViewpoint = Viewpoint(  center: Point(x: -117.195, y: 34.058, spatialReference: .wgs84),  scale: 5e4  )  return map  }()   /// The graphics overlay for the marker graphic.  let graphicsOverlay = GraphicsOverlay()   /// The red map marker graphic used to indicate a tap location on the map.  let markerGraphic = {  // Create a symbol using the image from the project assets.  let markerImage = UIImage.redMarker  let markerSymbol = PictureMarkerSymbol(image: .redMarker)   // Change the symbol's offsets, so it aligns properly to a given point.  markerSymbol.leaderOffsetY = markerImage.size.height / 2  markerSymbol.offsetY = markerImage.size.height / 2   // Create a graphic with the symbol.  return Graphic(symbol: markerSymbol)  }()   /// The locator task for reverse geocoding.  let locatorTask = LocatorTask(url: .geocodeServer)   /// The parameters for the reverse geocode operation.  let reverseGeocodeParameters = {  let parameters = ReverseGeocodeParameters()  parameters.addResultAttributeNames(["Address", "City", "RegionAbbr"])  parameters.maxResults = 1  return parameters  }()   init() {  graphicsOverlay.addGraphic(markerGraphic)  }  } }  private extension URL {  /// A URL to a geocode server on ArcGIS Online.  static var geocodeServer: URL {  URL(string: "https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer")!  } }  #Preview {  FindAddressWithReverseGeocodeView() }

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