Learn how to find an address or place with a search bar and the geocoding service.
Overview of how to search for an addressGeocoding is the process of converting address or place text into a location. The geocoding service can search for an address or a place and perform reverse geocoding.
In this tutorial, you use a search bar in the user interface to access the Geocoding service and search for addresses and places.
Mapping and location services guideFor more background information about the topics in this tutorial, visit Geocode in the Mapping and location services guide. To learn more about the service, visit Geocoding service.
PrerequisitesBefore starting this tutorial:
You need an ArcGIS Location Platform or ArcGIS Online account.
Your system meets the system requirements.
To access the secure ArcGIS location services used in this tutorial, you must implement API key authentication or user authentication using an ArcGIS Location Platform or an ArcGIS Online account.
You can implement API key authentication or user authentication in this tutorial. Compare the differences below:
API key authentication
Learn more in API key authentication.
User authentication
Learn more in User authentication.
Security and authentication guideTo learn more about the different types of authentication, visit Types of authentication.
Create a new API key access token with privileges to access the secure resources used in this tutorial.
Complete the Create an API key tutorial and create an API key with the following privilege(s):
Copy and paste the API key access token into a safe location. It will be used in a later step.
Create new OAuth credentials to access the secure resources used in this tutorial.
Complete the Create OAuth credentials for user authentication tutorial to obtain a Client ID and Redirect URL.
A Client ID
uniquely identifies your app on the authenticating server. If the server cannot find an app with the provided Client ID, it will not proceed with authentication.
The Redirect URL
(also referred to as a callback url) is used to identify a response from the authenticating server when the system returns control back to your app after an OAuth login. Since it does not necessarily represent a valid endpoint that a user could navigate to, the redirect URL can use a custom scheme, such as my-app://auth
. It is important to make sure the redirect URL used in your app's code matches a redirect URL configured on the authenticating server.
Copy and paste the Client ID and Redirect URL into a safe location. They will be used in a later step.
All users that access this application need account privileges to access the ArcGIS Basemap Styles service and the ArcGIS Geocoding service.
Develop or DownloadYou have two options for completing this tutorial:
Option 1: Develop the codeTo start the tutorial, complete the Display a map tutorial. This creates a map to display the Santa Monica Mountains in California using the topographic basemap from the ArcGIS basemap styles service.
Continue with the following instructions to add a search bar to the user interface and search for an address or place using the ArcGIS Geocoding service. First, you need to set the develop credentials in your app so that your app users can access the ArcGIS Geocoding service.
Set developer credentialsIf you implemented API key authentication in the Display a map tutorial, the API key access token will only have the Basemaps privilege. The Search for an address tutorial requires the Geocoding privilege to search for an address using the LocatorTask
. To create an API Key access token that has the Basemaps and Geocoding privileges, see the Set up authentication step and then follow the instructions below.
Pass your API Key access token to the ArcGISEnvironment
.
In the Project Navigator, click MainApp.swift.
Set the ArcGISEnvironment.apiKey
property with your API key access token.
MainApp.swift
Use dark colors for code blocks
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
ArcGISEnvironment.apiKey = APIKey("<#YOUR-ACCESS-TOKEN#>")
Best Practice: The access token is stored directly in the code as a convenience for this tutorial. Do not store credentials directly in source code in a production environment.
Use the Authenticator
toolkit component to manage your OAuth credentials and pass it to the ArcGISEnvironment
.
In the Project Navigator, click MainApp.swift.
Set your PortalURL
, clientID
and redirectURL
values.
MainApp.swift
Use dark colors for code blocks
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
authenticator = Authenticator(oAuthUserConfigurations: [
OAuthUserConfiguration(
portalURL: URL(string: "<#YOUR-PORTAL-URL#>")!,
clientID: ""<#YOUR-CLIENT-ID#>"",
redirectURL: URL(string: "<#YOUR-REDIRECT-URL#>")!
)
])
ArcGISEnvironment.authenticationManager.handleChallenges(using: authenticator)
Best Practice: The OAuth credentials are stored directly in the code as a convenience for this tutorial. Do not store credentials directly in source code in a production environment.
Update the mapIn Xcode, in the Project Navigator, click ContentView.swift.
In the editor, change the map and viewpoint into two separate @State
variables so that the viewpoint can be changed as the geocode results change.
ContentView.swift
Use dark colors for code blocks
54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 55 56 56 56 57 58 59 60 61 62 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 62 62
Change line Change line Change line Change line Change line Change line1
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
struct ContentView: View {
@State private var map = Map(basemapStyle: .arcGISImagery)
@State private var viewpoint: Viewpoint? = Viewpoint(
latitude: 34.02700,
longitude: -118.80500,
scale: 72_000
)
Create a private class named Model
of type ObservableObject
and add a @StateObject
variable of the Model
to the ContentView
. See the programming patterns page for more information on how to manage states.
ContentView.swift
Use dark colors for code blocks
15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 16 17 18 19 20 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 22 23 24 25 26 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 28
Add line. Add line. Add line. Add line.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
import SwiftUI
import ArcGIS
private class Model: ObservableObject {
}
struct ContentView: View {
@StateObject private var model = Model()
}
Create a GraphicsOverlay
named graphicsOverlay
in the Model
class. A graphics overlay is a container for graphics.
A graphics overlay is a container for graphics. It is used with a map view to display graphics on a map. You can add more than one graphics overlay to a map view. Graphics overlays are displayed on top of all the other layers.
ContentView.swift
Use dark colors for code blocks
19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 20 21 22 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24
Add line.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
private class Model: ObservableObject {
let graphicsOverlay: GraphicsOverlay
}
Lastly, add the viewpoint and graphics overlay to the map view.
ContentView.swift
Use dark colors for code blocks
87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 88 89 90 91 91 91 91 91 91 91 91 91 91 91 91 91 91 91 91 91 92 92 92
Change line1
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
var body: some View {
MapView(map: map, viewpoint: viewpoint, graphicsOverlays: [model.graphicsOverlay])
}
Graphics are added as a visual means to display the search result on the map.
Create a private property named textGraphic
in the Model
class. This graphic will be used to display the result's text label.
A TextSymbol
is used to display text at a location on the map view.
ContentView.swift
Expand
Use dark colors for code blocks19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 20 21 22 23 23 23 23 23 24 25 26 27 28 29 30 31 32 33 34 35 35 35 35 35 35 35 35 35 35 35 35 35 35 36 36 36 36 36 36 36 36 36 36 36 36 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 14 14 14 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -2 -2 -2
Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line.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
private class Model: ObservableObject {
let graphicsOverlay: GraphicsOverlay
let textGraphic: Graphic = {
let textSymbol = TextSymbol(
text: "",
color: .black,
size: 14,
horizontalAlignment: .center,
verticalAlignment: .bottom
)
textSymbol.backgroundColor = .white
return Graphic(symbol: textSymbol)
}()
}
Create a private property named markerGraphic
in the Model
class. This graphic will be used to display the result's location.
ContentView.swift
Expand
Use dark colors for code blocks19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 20 21 22 23 23 23 23 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 44 44 44 44 45 45 45 45 45 45 45 45 45 45 45 45 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 23 23 23 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 7 7 7
Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line.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
private class Model: ObservableObject {
let graphicsOverlay: GraphicsOverlay
let textGraphic: Graphic = {
let textSymbol = TextSymbol(
text: "",
color: .black,
size: 14,
horizontalAlignment: .center,
verticalAlignment: .bottom
)
textSymbol.backgroundColor = .white
return Graphic(symbol: textSymbol)
}()
let markerGraphic: Graphic = {
let markerSymbol = SimpleMarkerSymbol(
style: .square,
color: .red,
size: 14
)
return Graphic(symbol: markerSymbol)
}()
}
Create an init
function for the Model
class. Create a GraphicsOverlay
with the textGraphic
and markerGraphic
and assign it to the model's graphics overlay. This function will be called when Model
is initialized.
Because textGraphic
and markerGraphic
haven't yet specified a Geometry
, they will not be visible.
ContentView.swift
Expand
Use dark colors for code blocks19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 20 21 22 23 23 23 23 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 49 49 49 49 49 49 49 49 49 49 49 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 27 27 27 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 11 11 11
Add line. Add line. Add line.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
private class Model: ObservableObject {
let graphicsOverlay: GraphicsOverlay
let textGraphic: Graphic = {
let textSymbol = TextSymbol(
text: "",
color: .black,
size: 14,
horizontalAlignment: .center,
verticalAlignment: .bottom
)
textSymbol.backgroundColor = .white
return Graphic(symbol: textSymbol)
}()
let markerGraphic: Graphic = {
let markerSymbol = SimpleMarkerSymbol(
style: .square,
color: .red,
size: 14
)
return Graphic(symbol: markerSymbol)
}()
init() {
graphicsOverlay = GraphicsOverlay(graphics: [textGraphic, markerGraphic])
}
}
Geocoding is implemented with a locator, typically created by referencing a service such as the Geocoding service or, for offline geocoding, by referencing locator data contained in a mobile package. Geocoding parameters can be used to fine-tune the results, such as setting the maximum number of results or requesting additional attributes in the results.
Create a LocatorTask
property in the Model
, named locator
, based on the ArcGIS Geocoding service hosted by ESRI.
A locator task is used to convert an address to a point (geocode) or vice-versa (reverse geocode). An address includes any type of information that distinguishes a place. A locator involves finding matching locations for a given address. Reverse-geocoding is the opposite and finds the closest address for a given point.
ContentView.swift
Expand
Use dark colors for code blocks19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 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 53 53 53 53 53 53 53 53 53 53 53 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 31 31 31 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 15 15 15
Add line. Add line. Add line.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
private class Model: ObservableObject {
let graphicsOverlay: GraphicsOverlay
let locator = LocatorTask(
url: URL(string: "https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer")!
)
let textGraphic: Graphic = {
let textSymbol = TextSymbol(
text: "",
color: .black,
size: 14,
horizontalAlignment: .center,
verticalAlignment: .bottom
)
textSymbol.backgroundColor = .white
return Graphic(symbol: textSymbol)
}()
let markerGraphic: Graphic = {
let markerSymbol = SimpleMarkerSymbol(
style: .square,
color: .red,
size: 14
)
return Graphic(symbol: markerSymbol)
}()
init() {
graphicsOverlay = GraphicsOverlay(graphics: [textGraphic, markerGraphic])
}
}
Attention
ArcGIS Enterprise users do not have access to this ArcGIS Geocoding service hosted by ESRI. If you are building an app for ArcGIS Enterprise users, you need to use a geocoding service that is hosted in the users' ArcGIS Enterprise. Contact the ArcGIS Enterprise administrator for more information.
In the ContentView
, create a private String
variable named searchText
with the @State
property wrapper. This will hold the user input and be used to perform the geocode operation.
ContentView.swift
Expand
Use dark colors for code blocks54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 55 56 57 58 59 60 61 62 63 64 65 66 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 68 69 70 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 71 72 73 74
Add line.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
struct ContentView: View {
@StateObject private var model = Model()
@State private var map = Map(basemapStyle: .arcGISImagery)
@State private var viewpoint: Viewpoint? = Viewpoint(
latitude: 34.02700,
longitude: -118.80500,
scale: 72_000
)
@State private var searchText: String = ""
var body: some View {
MapView(map: map, viewpoint: viewpoint, graphicsOverlays: [model.graphicsOverlay])
}
}
Create a private, asynchronous function named geocode(with:)
. This function will be called when the user inputs an address.
ContentView.swift
Expand
Use dark colors for code blocks54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 69 70 71 72 73 74 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 76 77 78
Add line. Add line. Add line.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
struct ContentView: View {
@StateObject private var model = Model()
@State private var map = Map(basemapStyle: .arcGISImagery)
@State private var viewpoint: Viewpoint? = Viewpoint(
latitude: 34.02700,
longitude: -118.80500,
scale: 72_000
)
@State private var searchText: String = ""
private func geocode(with searchText: String) async throws {
}
var body: some View {
MapView(map: map, viewpoint: viewpoint, graphicsOverlays: [model.graphicsOverlay])
}
}
Within the new function, create GeocodeParameters
, and its attributes as follows:
addResultAttributeName
. *
is used to return all attributes.maxResults
. In this tutorial, only return the best match by passing in 1
. Results are ordered by score
, so just returning the first result will return the highest scoring result.outputSpatialReference
. By default the output spatial reference is determined by the geocode service. For optimal performance when displaying the geocode result, ensure the returned coordinates match those of the map view by providing mapView.spatialReference
as a parameter.When geocoding an address, you can optionally provide GeocodeParameters
to control certain aspects of the geocoding operation, and specify the kinds of results to return from the locator task.
ContentView.swift
Expand
Use dark colors for code blocks67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 68 69 70 71 72 73 74 74 74 74 74 74 74 74 74 74 74 74 75 75 75 75 75 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 59 59 59
Add line. Add line. Add line. Add line.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
private func geocode(with searchText: String) async throws {
let parameters = GeocodeParameters()
parameters.addResultAttributeName("*")
parameters.maxResults = 1
parameters.outputSpatialReference = map.spatialReference
}
Perform the geocode operation by calling geocode(forSearchText:using:)
and supplying the search text and the geocode parameters. The result obtained from the geocode operation will be displayed as a graphic in the map view's graphics overlay.
ContentView.swift
Expand
Use dark colors for code blocks67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 86 86 86 86 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 70 70 70
Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line.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
private func geocode(with searchText: String) async throws {
let parameters = GeocodeParameters()
parameters.addResultAttributeName("*")
parameters.maxResults = 1
parameters.outputSpatialReference = map.spatialReference
let geocodeResults = try await model.locator.geocode(forSearchText: searchText, using: parameters)
if let firstResult = geocodeResults.first,
let extent = firstResult.extent,
let location = firstResult.displayLocation,
let symbol = model.textGraphic.symbol as? TextSymbol {
viewpoint = Viewpoint(boundingGeometry: extent)
model.markerGraphic.geometry = location
model.textGraphic.geometry = location
symbol.text = firstResult.label
}
}
To search an address using the application, add a UI element to prompt the user for text input.
In the body
, add an overlay
to the MapView
. Set the alignment
to the top, add padding all around, and set the background.
ContentView.swift
Expand
Use dark colors for code blocks87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 88 89 90 91 92 93 93 93 93 93 93 93 93 93 93 93 94 95 96 97 98 98 98
Add line. Add line. Add line. Add line. Add line.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
var body: some View {
MapView(map: map, viewpoint: viewpoint, graphicsOverlays: [model.graphicsOverlay])
.overlay(alignment: .top) {
.padding(EdgeInsets(top: 60, leading: 10, bottom: 10, trailing: 10))
.background(.thinMaterial, ignoresSafeAreaEdges: .horizontal)
}
}
Within the overlay, add the following:
TextField
: Pass in "Enter address" as the titleKey
and the searchText
variable as a binding for the text
parameterSpacer()
: Add space in between the text field and button.Button
: Label it "Search" and using a Task
method, call the geocode(with:)
function and pass in searchText
ContentView.swift
Expand
Use dark colors for code blocks87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 108 108
Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line.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
var body: some View {
MapView(map: map, viewpoint: viewpoint, graphicsOverlays: [model.graphicsOverlay])
.overlay(alignment: .top) {
HStack {
TextField("Enter address", text: $searchText)
Spacer()
Button("Search") {
Task {
try await geocode(with: searchText)
}
}
}
.padding(EdgeInsets(top: 60, leading: 10, bottom: 10, trailing: 10))
.background(.thinMaterial, ignoresSafeAreaEdges: .horizontal)
}
}
Press Command + R to run the app.
If you are using the Xcode simulator your system must meet these minimum requirements: macOS 14 (Sonoma), Xcode 16, iOS 18. If you are using a physical device, then refer to the system requirements.
You should see a search box at the top of the map. Search for an address by entering an address and tap the Search button. The result of the search should display on the map as a red square with the address displayed on top.
Alternatively, you can download the tutorial solution, as follows.
Option 2: Download the solutionClick the Download solution
link under Solution and unzip the file to a location on your machine.
Open the .xcodeproj
file in Xcode.
Since the downloaded solution does not contain authentication credentials, you must add the developer credentials that you created in the Set up authentication section.
Set developer credentials in the solutionTo allow your app users to access ArcGIS location services, use the developer credentials that you created in the Set up authentication step to authenticate requests for resources.
Pass your API Key access token to the ArcGISEnvironment
.
In the Project Navigator, click MainApp.swift.
Set the AuthenticationMode
to .apiKey
.
MainApp.swift
Use dark colors for code blocks
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
// Change the `AuthenticationMode` to `.apiKey` if your application uses API key authentication.
private var authenticationMode: AuthenticationMode { .apiKey }
Set the apiKey
property with your API key access token.
MainApp.swift
Expand
Use dark colors for code blocks1
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
// Please enter an API key access token if your application uses API key authentication.
private let apiKey = APIKey("<#YOUR-ACCESS-TOKEN#>")
Best Practice: The access token is stored directly in the code as a convenience for this tutorial. Do not store credentials directly in source code in a production environment.
Use the Authenticator
toolkit component to manage your OAuth credentials and pass it to the ArcGISEnvironment
.
In the Project Navigator, click MainApp.swift.
Set the AuthenticationMode
to .user
.
MainApp.swift
Use dark colors for code blocks
1
2
3
// Change the `AuthenticationMode` to `.user` if your application uses OAuth credentials.
private var authenticationMode: AuthenticationMode { .user }
Set your portalURL
, clientID
and redirectURL
values.
MainApp.swift
Expand
Use dark colors for code blocks1
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
// Setup an `Authenticator` with OAuth configuration if your application uses OAuth credentials.
@ObservedObject var authenticator = Authenticator(
oAuthUserConfigurations: [
OAuthUserConfiguration(
// Please enter OAuth credentials for user authentication.
portalURL: URL(string: "<#YOUR-PORTAL-URL#>")!,
clientID: "<#YOUR-CLIENT-ID#>",
redirectURL: URL(string: "<#YOUR-REDIRECT-URL#>")!
)
]
)
Best Practice: The OAuth credentials are stored directly in the code as a convenience for this tutorial. Do not store credentials directly in source code in a production environment.
Run the solutionPress Command + R to run the app.
If you are using the Xcode simulator your system must meet these minimum requirements: macOS 14 (Sonoma), Xcode 16, iOS 18. If you are using a physical device, then refer to the system requirements.
You should see a search box at the top of the map. Search for an address by entering an address and tap the Search button. The result of the search should display on the map as a red square with the address displayed on top.
Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials:
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4