Learn how to apply renderers and label definitions to a feature layer based on attribute values.
Applications can display feature layer data with different styles to enhance the visualization. The type of Renderer
you choose depends on your application. A SimpleRenderer
applies the same symbol to all features, a UniqueValueRenderer
applies a different symbol to each unique attribute value, and a ClassBreaksRenderer
applies a symbol to a range of numeric values. Renderers are responsible for accessing the data and applying the appropriate symbol to each feature when the layer draws. You can also use a LabelDefinition
to show attribute information for features. Visit the Styles and data visualization documentation to learn more about styling layers.
You can also author, style and save web maps, web scenes, and layers as portal items and then add them to the map in your application. Visit the following tutorials to learn more about adding portal items.
In this tutorial, you will apply different renderers to enhance the visualization of three feature layers with data for the Santa Monica Mountains: Trailheads with a single symbol, Trails based on elevation change and bike use, and Parks and Open Spaces based on the type of park.
PrerequisitesBefore starting this tutorial:
You need an ArcGIS Location Platform or ArcGIS Online account.
Your system meets the system requirements.
You 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.
Open an Xcode project.xcodeproj
project you created by completing the Display a map tutorial.Create a configuration file to specify constants that can be used by the app to connect to data and resources.
Add a new swift file named AppConfiguration.swift.
Create five static URL
s: four for accessing feature layers, and a fifth for accessing a static image for use in a picture marker symbol. You will use these resources in future steps.
AppConfiguration.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
extension URL {
static let bikesTrails = URL(string: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0")!
static let parksAndOpenSpaces = URL(string: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Parks_and_Open_Space/FeatureServer/0")!
static let trails = URL(string: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0")!
static let trailheads = URL(string: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0")!
static let trailheadImage = URL(string: "https://static.arcgis.com/images/Symbols/NPS/npsPictograph_0231b.png")!
}
Add a helper method that creates a feature layer from a given URL
.
Open ContentView.swift
in the Project Navigator. Add a new method named makeFeatureLayer(url: URL)
.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
private func makeFeatureLayer(url: URL) -> FeatureLayer {
let serviceFeatureTable = ServiceFeatureTable(url: url)
let featureLayer = FeatureLayer(featureTable: serviceFeatureTable)
return featureLayer
}
Create a method to apply a different symbol for each type of park area to the Parks and Open Spaces feature layer.
Add a new method named makeOpenSpaceLayer()
in ContentView.swift
.
UniqueValue
assigns a symbol to a value or values. A unique value renderer uses a collection of unique values to assign the appropriate symbol for each feature it renderers.
For this example, the renderer uses a feature's TYPE
attribute value to apply the correct symbol.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
private func makeOpenSpaceLayer() {
// Creates a parks and open spaces feature layer.
let featureLayer = makeFeatureLayer(url: .parksAndOpenSpaces)
// Creates fill symbols.
let purpleFillSymbol = SimpleFillSymbol(style: .solid, color: .purple, outline: .none)
let greenFillSymbol = SimpleFillSymbol(style: .solid, color: .green, outline: .none)
let blueFillSymbol = SimpleFillSymbol(style: .solid, color: .blue, outline: .none)
let redFillSymbol = SimpleFillSymbol(style: .solid, color: .red, outline: .none)
// Creates a unique value for natural areas, regional open spaces, local parks & regional recreation parks.
let naturalAreas = UniqueValue(description: "Natural Areas", label: "Natural Areas", symbol: purpleFillSymbol, values: ["Natural Areas"])
let regionalOpenSpace = UniqueValue(description: "Regional Open Space", label: "Regional Open Space", symbol: greenFillSymbol, values: ["Regional Open Space"])
let localPark = UniqueValue(description: "Local Park", label: "Local Park", symbol: blueFillSymbol, values: ["Local Park"])
let regionalRecreationPark = UniqueValue(description: "Regional Recreation Park", label: "Regional Recreation Park", symbol: redFillSymbol, values: ["Regional Recreation Park"])
// Creates and assigns a unique value renderer to the feature layer.
let openSpacesUniqueValueRenderer = UniqueValueRenderer(fieldNames: ["TYPE"], uniqueValues: [naturalAreas, regionalOpenSpace, localPark, regionalRecreationPark], defaultLabel: "Open Spaces", defaultSymbol: .none)
featureLayer.renderer = openSpacesUniqueValueRenderer
// Sets the layer opacity to semi-transparent.
featureLayer.opacity = 0.2
// Adds the feature layer to the map.
map.addOperationalLayer(featureLayer)
}
Update the MapView
task to call the new makeOpenSpaceLayer()
method.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
// Displays the map.
MapView(map: map)
.task {
makeOpenSpaceLayer()
}
Press Command + R to run the app.
When the app opens, Parks and Open Spaces feature layer is added to the map. The map displays the different types of parks and open spaces with four unique symbols.
Add a layer with a class breaks rendererCreate a method to apply a different symbol for each of the five ranges of elevation gain to the Trails feature layer.
Add a new method named addTrailsLayer()
.
A ClassBreak
assigns a symbol to a range of values.
For this example, the renderer uses each feature's ELEV_GAIN
attribute value to classify it into a defined range (class break) and apply the corresponding symbol.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
private func addTrailsLayer() {
// Creates a trails feature layer.
let featureLayer = makeFeatureLayer(url: .trails)
// Creates simple line symbols.
let firstClassSymbol = SimpleLineSymbol(style: .solid, color: .purple, width: 3.0)
let secondClassSymbol = SimpleLineSymbol(style: .solid, color: .purple, width: 4.0)
let thirdClassSymbol = SimpleLineSymbol(style: .solid, color: .purple, width: 5.0)
let fourthClassSymbol = SimpleLineSymbol(style: .solid, color: .purple, width: 6.0)
let fifthClassSymbol = SimpleLineSymbol(style: .solid, color: .purple, width: 7.0)
// Creates 5 class breaks.
let firstClassBreak = ClassBreak(description: "Under 500", label: "0 - 500", minValue: 0.0, maxValue: 500.0, symbol: firstClassSymbol)
let secondClassBreak = ClassBreak(description: "501 to 1000", label: "501 - 1000", minValue: 501.0, maxValue: 1000.0, symbol: secondClassSymbol)
let thirdClassBreak = ClassBreak(description: "1001 to 1500", label: "1001 - 1500", minValue: 1001.0, maxValue: 1500.0, symbol: thirdClassSymbol)
let fourthClassBreak = ClassBreak(description: "1501 to 2000", label: "1501 - 2000", minValue: 1501.0, maxValue: 2000.0, symbol: fourthClassSymbol)
let fifthClassBreak = ClassBreak(description: "2001 to 2300", label: "2001 - 2300", minValue: 2001.0, maxValue: 2300.0, symbol: fifthClassSymbol)
let elevationBreaks = [firstClassBreak, secondClassBreak, thirdClassBreak, fourthClassBreak, fifthClassBreak]
// Creates and assigns a class breaks renderer to the feature layer.
let elevationClassBreaksRenderer = ClassBreaksRenderer(fieldName: "ELEV_GAIN", classBreaks: elevationBreaks)
featureLayer.renderer = elevationClassBreaksRenderer
// Sets the layer opacity to semi-transparent.
featureLayer.opacity = 0.75
// Adds the feature layer to the map.
map.addOperationalLayer(featureLayer)
}
Update the MapView
task to call the new addTrailsLayer()
method.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
// Displays the map.
MapView(map: map)
.task {
makeOpenSpaceLayer()
addTrailsLayer()
}
Press Command + R to run the app.
When the app opens, the Trails feature layer is added to the map. The map displays trails with different symbols depending on trail elevation.
Add layers with definition expressionsYou can use a definition expression to define a subset of features to display. Features that do not meet the expression criteria are not displayed by the layer. In the following steps, you will create two methods that use a definition expression to apply a symbol to a subset of features in the Trails feature layer.
FeatureLayer.definitionExpression
uses a SQL expression to limit the features available for query and display. Your code will create two layers that each display a different subset of trails based on the value for the USE_BIKE
field. Trails that allow bikes will be symbolized with a blue symbol ("USE_BIKE = 'Yes'"
) and those that don't will be red ("USE_BIKE = 'No'"
). Another way to symbolize these features would be to create a UniqueValueRenderer
that applies a different symbol for these values.
Add a method with a definition expression to filter for trails that permit bikes.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
private func addBikeOnlyTrailsLayer() {
// Creates a trails feature layer.
let featureLayer = makeFeatureLayer(url: .bikesTrails)
// Writes a definition expression to filter for trails that do permit the use of bikes.
featureLayer.definitionExpression = "USE_BIKE = 'Yes'"
// Creates and assigns a simple renderer to the feature layer.
let bikeTrailSymbol = SimpleLineSymbol(style: .dot, color: .blue, width: 2.0)
let bikeTrailRenderer = SimpleRenderer(symbol: bikeTrailSymbol)
featureLayer.renderer = bikeTrailRenderer
// Adds the feature layer to the map.
map.addOperationalLayer(featureLayer)
}
Add another method with a definition expression to filter for trails that don't allow bikes.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
private func addNoBikeTrailsLayer() {
// Creates a no bike trails feature layer.
let featureLayer = makeFeatureLayer(url: .bikesTrails)
// Writes a definition expression to filter for trails that don't permit the use of bikes.
featureLayer.definitionExpression = "USE_BIKE = 'No'"
// Creates and assigns a simple renderer to the feature layer.
let noBikeTrailSymbol = SimpleLineSymbol(style: .dot, color: .red, width: 2.0)
let noBikeTrailRenderer = SimpleRenderer(symbol: noBikeTrailSymbol)
featureLayer.renderer = noBikeTrailRenderer
// Adds the feature layer to the map.
map.addOperationalLayer(featureLayer)
}
Update the MapView
task to call the new addBikeOnlyTrailsLayer()
and addNoBikeTrailsLayer()
methods.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
// Displays the map.
MapView(map: map)
.task {
makeOpenSpaceLayer()
addTrailsLayer()
addNoBikeTrailsLayer()
addBikeOnlyTrailsLayer()
}
Press Command + R to run the app.
When the app opens, two Trails feature layers are added to the map. One shows where bikes are permitted and the other where they are prohibited.
Add a layer with a label definitionCreate a method to style trailheads with hiker images and labels for the Trailheads feature layer.
Create a helper method named makeLabelDefinition()
to define a label definition based on a specific attribute of the feature layer TRL_NAME
. Also define label placement and symbol.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
private func makeLabelDefinition() -> LabelDefinition {
let trailHeadsTextSymbol = TextSymbol()
trailHeadsTextSymbol.color = .white
trailHeadsTextSymbol.size = 20.0
trailHeadsTextSymbol.haloColor = .red
trailHeadsTextSymbol.haloWidth = 2.0
trailHeadsTextSymbol.fontFamily = "Noto Sans"
trailHeadsTextSymbol.fontStyle = .italic
trailHeadsTextSymbol.fontWeight = .normal
// Makes an arcade label expression.
let expression = "$feature.TRL_NAME"
let arcadeLabelExpression = ArcadeLabelExpression(arcadeString: expression)
let labelDefinition = LabelDefinition(labelExpression: arcadeLabelExpression, textSymbol: trailHeadsTextSymbol)
labelDefinition.placement = .pointAboveCenter
return labelDefinition
}
Add a method named addTrailheadsLayer()
.
Use a PictureMarkerSymbol
to draw a trailhead hiker image. Use the LabelDefinition
to label each trailhead by its name.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
private func addTrailheadsLayer() {
// Creates a trailheads feature layer.
let featureLayer = makeFeatureLayer(url: .trailheads)
let pictureMarkerSymbol = PictureMarkerSymbol(url: .trailheadImage)
pictureMarkerSymbol.height = 18.0
pictureMarkerSymbol.width = 18.0
let simpleRenderer = SimpleRenderer(symbol: pictureMarkerSymbol)
featureLayer.renderer = simpleRenderer
featureLayer.labelsAreEnabled = true
let trailHeadsDefinition = makeLabelDefinition()
featureLayer.addLabelDefinition(trailHeadsDefinition)
// Adds the feature layer to the map.
map.addOperationalLayer(featureLayer)
}
Update the MapView
task to call the new addTrailheadsLayer()
method.
ContentView.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
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
162
163
164
165
166
167
168
169
170
171
172
173
// Displays the map.
MapView(map: map)
.task {
makeOpenSpaceLayer()
addTrailsLayer()
addNoBikeTrailsLayer()
addBikeOnlyTrailsLayer()
addTrailheadsLayer()
}
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.
When the app opens, all the layers you've created and symbolized are displayed on the map.
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 first set up authentication to create credentials, and then add the developer credentials to the solution.
Set up authenticationTo 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.
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.
When the app opens, all the layers you've created and symbolized are displayed on the map.
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