Display User Location
This section of the iOS Maps SDK provides developers with the necessary tools and guidelines to incorporate user location functionality into their applications. This functionality allows users to see their current location on the map, providing a more personalized and interactive experience.
Permissions
This section explains the importance of obtaining the necessary location permissions from the user. It provides information on how to request location permissions and handle user responses. Ensuring that the appropriate permissions are obtained is crucial for accessing and displaying the user's location accurately and securely.
Add the following to the info.plist
1<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
2<string>YOUR_DESCRIPTION</string>
3<key>NSLocationAlwaysUsageDescription</key>
4<string>YOUR_DESCRIPTION</string>
Replace YOUR_DESCRIPTION with a short description of the location information your application uses. Permission requests are automatically triggered by the Maps SDK when obtaining location information
Location provider/Component

You can use the following code to display the current location on the map. mapView.showsUserLocation = true
You can also use your own location component. Here is an example of MapView using a custom Location component.
- Create custom MapLocationManager
1import Nbmap
2import CoreLocation
3class CustomMapLocationManager: NSObject,NGLLocationManager {
4
5 var delegate: NGLLocationManagerDelegate? {
6 didSet {
7 locationManager.delegate = self
8 }
9 }
10
11 // Replay with your own location manager
12 private let locationManager = CLLocationManager()
13
14 var headingOrientation: CLDeviceOrientation {
15 get {
16 return locationManager.headingOrientation
17 }
18 set {
19 locationManager.headingOrientation = newValue
20 }
21 }
22
23 var desiredAccuracy: CLLocationAccuracy {
24 get {
25 return locationManager.desiredAccuracy
26 }
27 set {
28 locationManager.desiredAccuracy = newValue
29 }
30 }
31
32 var authorizationStatus: CLAuthorizationStatus {
33 if #available(iOS 14.0, *) {
34 return locationManager.authorizationStatus
35 } else {
36 return CLLocationManager.authorizationStatus()
37 }
38 }
39
40 var activityType: CLActivityType {
41 get {
42 return locationManager.activityType
43 }
44 set {
45 locationManager.activityType = newValue
46 }
47 }
48
49 @available(iOS 14.0, *)
50 var accuracyAuthorization: CLAccuracyAuthorization {
51 return locationManager.accuracyAuthorization
52 }
53
54 @available(iOS 14.0, *)
55 func requestTemporaryFullAccuracyAuthorization(withPurposeKey purposeKey: String) {
56 locationManager.requestTemporaryFullAccuracyAuthorization(withPurposeKey: purposeKey)
57 }
58
59 func dismissHeadingCalibrationDisplay() {
60 locationManager.dismissHeadingCalibrationDisplay()
61 }
62
63 func requestAlwaysAuthorization() {
64 locationManager.requestAlwaysAuthorization()
65 }
66
67 func requestWhenInUseAuthorization() {
68 locationManager.requestWhenInUseAuthorization()
69 }
70
71 func startUpdatingHeading() {
72 locationManager.startUpdatingHeading()
73 }
74
75 func startUpdatingLocation() {
76 locationManager.startUpdatingLocation()
77 }
78
79 func stopUpdatingHeading() {
80 locationManager.stopUpdatingHeading()
81 }
82
83 func stopUpdatingLocation() {
84 locationManager.stopUpdatingLocation()
85 }
86
87 deinit {
88 locationManager.stopUpdatingLocation()
89 locationManager.stopUpdatingHeading()
90 locationManager.delegate = nil
91 delegate = nil
92 }
93
94}
95// MARK: - CLLocationManagerDelegate
96extension CustomMapLocationManager : CLLocationManagerDelegate {
97
98 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
99 delegate?.locationManager(self, didUpdate: locations)
100 }
101
102 func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
103 delegate?.locationManager(self, didUpdate: newHeading)
104 }
105
106 func locationManagerShouldDisplayHeadingCalibration(_ manager: CLLocationManager) -> Bool {
107 return delegate?.locationManagerShouldDisplayHeadingCalibration(self) ?? false
108 }
109
110 func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
111 delegate?.locationManager(self, didFailWithError: error)
112 }
113
114
115 @available(iOS 14.0, *)
116 func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
117 delegate?.locationManagerDidChangeAuthorization(self)
118 }
119}
- Use custom location manager
1import Foundation
2import UIKit
3import Nbmap
4class CustomLocationSourceViewController: UIViewController {
5 var nbMapView: NGLMapView! {
6 didSet {
7 oldValue?.removeFromSuperview()
8 if let mapView = nbMapView {
9 view.insertSubview(mapView, at: 0)
10 }
11 }
12 }
13 override func viewDidLoad() {
14 super.viewDidLoad()
15 nbMapView = NGLMapView(frame:self.view.bounds)
16 nbMapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
17
18 /**
19 Custom the location source , The locationManager that this map view uses to start and stop the delivery of
20 location-related updates.
21 To receive the current user location, implement the
22 `-[NGLMapViewDelegate mapView:didUpdateUserLocation:]` and
23 `-[NGLMapViewDelegate mapView:didFailToLocateUserWithError:]` methods.
24 If setting this property to `nil` or if no custom manager is provided this
25 property is set to the default location manager.
26 `NGLMapView` uses a default location manager. If you want to substitute your
27 own location manager, you should do so by setting this property before setting
28 `showsUserLocation` to `YES`. To restore the default location manager,
29 set this property to `nil`.
30 */
31 nbMapView.locationManager = CustomMapLocationManager()
32 nbMapView.showsUserLocation = true
33 nbMapView.userTrackingMode = .follow
34 }
35}
Location Puck
The location puck refers to the graphical representation of the user's current location on the map. This subsection discusses how to customize and style the location puck to match the app's design and provide a clear visual indication of the user's position on the map. Developers can learn how to adjust the size, color, and shape of the location puck to meet their application's requirements.

Code example: show user location on the map and customise puck view
1import UIKit
2import Nbmap
3class CustomPuckViewController: UIViewController {
4 var nbMapView: NGLMapView! {
5 didSet {
6 oldValue?.removeFromSuperview()
7 if let mapView = nbMapView {
8 view.insertSubview(mapView, at: 0)
9 }
10 }
11 }
12 override func viewDidLoad() {
13 super.viewDidLoad()
14 nbMapView = NGLMapView(frame:self.view.bounds)
15 nbMapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
16 nbMapView.delegate = self
17 nbMapView.userTrackingMode = .follow
18 }
19}
20// MARK: - NGLMapViewDelegate
21extension CustomPuckViewController: NGLMapViewDelegate {
22
23 /**
24 Asks the user styling options for each default user location annotation view.
25
26 This method is called many times during gesturing, so you should avoid performing
27 complex or performance-intensive tasks in your implementation.
28
29 @param mapView The map view that is tracking the user's location.
30 */
31 func mapView(styleForDefaultUserLocationAnnotationView mapView: NGLMapView) -> NGLUserLocationAnnotationViewStyle {
32 let locationStyle = NGLUserLocationAnnotationViewStyle()
33 /**
34 The fill color for the puck view.
35 */
36 locationStyle.puckFillColor = UIColor.blue
37 /**
38 The shadow color for the puck view.
39 */
40 locationStyle.puckShadowColor = UIColor.red
41 /**
42 The shadow opacity for the puck view.
43 Set any value between 0.0 and 1.0.
44 The default value of this property is equal to `0.25`
45 */
46 locationStyle.puckShadowOpacity = 0.25
47 /**
48 The fill color for the arrow puck.
49 */
50 locationStyle.puckArrowFillColor = UIColor.black
51 /**
52 The fill color for the puck view.
53 */
54 locationStyle.haloFillColor = UIColor.white
55
56 if #available(iOS 14, *) {
57 /**
58 The halo fill color for the approximate view.
59 */
60 locationStyle.approximateHaloFillColor = UIColor.white
61 /**
62 The halo border color for the approximate view.
63 */
64 locationStyle.approximateHaloBorderColor = UIColor.white
65 /**
66 The halo border width for the approximate view.
67 The default value of this property is equal to `2.0`
68 */
69 locationStyle.approximateHaloBorderWidth = 2.0
70 /**
71 The halo opacity for the approximate view.
72 Set any value between 0.0 and 1.0
73 The default value of this property is equal to `0.15`
74 */
75 locationStyle.approximateHaloOpacity = 0.15
76 }
77
78 return locationStyle
79 }
80
81 /**
82 Returns a view object to mark the given point annotation object on the map.
83 Implement this method to mark a point annotation with a view object. If you
84 want to mark a particular point annotation with a static image instead, omit
85 this method or have it return `nil` for that annotation, then implement
86 `-mapView:imageForAnnotation:` instead.
87 Annotation views are compatible with UIKit, Core Animation, and other Cocoa
88 Touch frameworks. On the other hand, static annotation images use less memory
89 and draw more quickly than annotation views.
90 The user location annotation view can also be customized via this method. When
91 `annotation` is an instance of `NGLUserLocation` (or equal to the map view's
92 `userLocation` property), return an instance of `NGLUserLocationAnnotationView`
93 (or a subclass thereof).
94 @param mapView The map view that requested the annotation view.
95 @param annotation The object representing the annotation that is about to be
96 displayed.
97 @return The view object to display for the given annotation or `nil` if you
98 want to display an annotation image instead.
99 */
100 func mapView(_ mapView: NGLMapView, viewFor annotation: NGLAnnotation) -> NGLAnnotationView? {
101 let annotationView = CustomUserLocationAnnotationView(frame: CGRect.zero)
102 annotationView.frame = CGRect(x:0, y:0, width:annotationView.intrinsicContentSize.width, height:annotationView.intrinsicContentSize.height);
103 return annotationView
104 }
105
106}
Location tracking mode
This subsection focuses on different location tracking modes available in the iOS Maps SDK. It explains the concept of location tracking modes, such as "follow," "follow with course," and "follow with heading." Developers can understand how each tracking mode works and choose the appropriate one based on their application's needs. These modes enable the map to dynamically adjust and center on the user's location as they move, providing a smooth and intuitive user experience.
The provided code example demonstrates how to show the user's location on a map and change the tracking mode using the iOS Maps SDK.
1import UIKit
2import Nbmap
3enum LocationType {
4 case HidePuckView
5 case UpdateToFollow
6 case UpdateToFollowWithHeading
7 case UpdateToFollowWithCourse
8 case GetUserLocation
9}
10class LocationStyleViewController: UIViewController {
11 var nbMapView: NGLMapView! {
12 didSet {
13 oldValue?.removeFromSuperview()
14 if let mapView = nbMapView {
15 view.insertSubview(mapView, at: 0)
16 }
17 }
18 }
19
20 var button: UIButton!
21
22 let typeList = [
23 LocationType.HidePuckView,
24 LocationType.UpdateToFollow,
25 LocationType.UpdateToFollowWithCourse,
26 LocationType.UpdateToFollowWithHeading,
27 LocationType.GetUserLocation
28 ]
29
30 override func viewDidLoad() {
31 super.viewDidLoad()
32 nbMapView = NGLMapView(frame:self.view.bounds)
33 nbMapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
34 nbMapView.delegate = self
35
36 button = UIButton(type: .system)
37 button.setTitle("Settings", for: .normal)
38 button.addTarget(self, action: #selector(showSetings), for: .touchUpInside)
39 button.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
40 navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)
41 }
42
43 @objc func showSetings() {
44 let tableViewController = UITableViewController(style: .plain)
45 tableViewController.tableView.delegate = self
46 tableViewController.tableView.dataSource = self
47 tableViewController.title = "Locations Settings"
48 self.present(tableViewController, animated: true)
49 }
50
51 func performeSettings(tyle: LocationType) {
52 switch tyle {
53 case LocationType.UpdateToFollow:
54 nbMapView.setUserTrackingMode(.follow,animated: true,completionHandler: nil)
55 break
56 case LocationType.UpdateToFollowWithCourse:
57 nbMapView.setUserTrackingMode(.followWithCourse,animated: true,completionHandler: nil)
58 break
59 case LocationType.UpdateToFollowWithHeading:
60 nbMapView.setUserTrackingMode(.followWithHeading,animated: true,completionHandler: nil)
61 break
62 case LocationType.HidePuckView:
63 nbMapView.setUserTrackingMode(.none,animated: true,completionHandler: nil)
64 break
65 case LocationType.GetUserLocation:
66 if let userLocation = nbMapView.userLocation {
67 let location = userLocation.location
68 let isUpdating = userLocation.isUpdating
69 let title = userLocation.title
70 let subtitle = userLocation.subtitle ?? ""
71 print("location:" + location!.description)
72 print("isUpdating:" + String(isUpdating))
73 print("title:" + title)
74 print("subtitle:" + subtitle)
75 if let heading = userLocation.heading {
76 print(heading.description)
77 }
78 }
79 break
80 }
81
82 }
83}
84extension LocationStyleViewController: NGLMapViewDelegate {
85 func mapView(_ mapView: NGLMapView, didFinishLoading style: NGLStyle){
86
87 let camera = NGLMapCamera(lookingAtCenter: CLLocationCoordinate2DMake(12.94798778, 77.57375084),
88 acrossDistance:10000,
89 pitch:0,
90 heading:0)
91 nbMapView.fly(to: camera)
92
93 }
94
95 /**
96 Tells the user that the map view will begin tracking the user's location.
97 This method is called when the value of the `showsUserLocation` property
98 changes to `YES`.
99 @param mapView The map view that is tracking the user's location.
100 */
101 func mapViewWillStartLocatingUser(_ mapView: NGLMapView) {
102
103 }
104
105 /**
106 Tells the user that the map view has stopped tracking the user's location.
107 This method is called when the value of the `showsUserLocation` property
108 changes to `NO`.
109 @param mapView The map view that is tracking the user's location.
110 */
111 func mapViewDidStopLocatingUser(_ mapView: NGLMapView) {
112
113 }
114
115
116 /**
117 Asks the user styling options for each default user location annotation view.
118
119 This method is called many times during gesturing, so you should avoid performing
120 complex or performance-intensive tasks in your implementation.
121
122 @param mapView The map view that is tracking the user's location.
123 */
124 func mapView(styleForDefaultUserLocationAnnotationView mapView: NGLMapView) -> NGLUserLocationAnnotationViewStyle {
125 let locationStyle = NGLUserLocationAnnotationViewStyle()
126 /**
127 The fill color for the puck view.
128 */
129 locationStyle.puckFillColor = UIColor.blue
130 /**
131 The shadow color for the puck view.
132 */
133 locationStyle.puckShadowColor = UIColor.red
134 /**
135 The shadow opacity for the puck view.
136 Set any value between 0.0 and 1.0.
137 The default value of this property is equal to `0.25`
138 */
139 locationStyle.puckShadowOpacity = 0.25
140 /**
141 The fill color for the arrow puck.
142 */
143 locationStyle.puckArrowFillColor = UIColor.black
144 /**
145 The fill color for the puck view.
146 */
147 locationStyle.haloFillColor = UIColor.white
148
149 if #available(iOS 14, *) {
150 /**
151 The halo fill color for the approximate view.
152 */
153 locationStyle.approximateHaloFillColor = UIColor.white
154 /**
155 The halo border color for the approximate view.
156 */
157 locationStyle.approximateHaloBorderColor = UIColor.white
158 /**
159 The halo border width for the approximate view.
160 The default value of this property is equal to `2.0`
161 */
162 locationStyle.approximateHaloBorderWidth = 2.0
163 /**
164 The halo opacity for the approximate view.
165 Set any value between 0.0 and 1.0
166 The default value of this property is equal to `0.15`
167 */
168 locationStyle.approximateHaloOpacity = 0.15
169 }
170
171 return locationStyle
172 }
173
174 /**
175 Tells the user that the location of the user was updated.
176 While the `showsUserLocation` property is set to `YES`, this method is called
177 whenever a new location update is received by the map view. This method is also
178 called if the map view's user tracking mode is set to
179 `NGLUserTrackingModeFollowWithHeading` and the heading changes, or if it is set
180 to `NGLUserTrackingModeFollowWithCourse` and the course changes.
181 This method is not called if the application is currently running in the
182 background. If you want to receive location updates while running in the
183 background, you must use the Core Location framework.
184 private @param mapView The map view that is tracking the user's location.
185 @param userLocation The location object represents the user's latest
186 location. This property may be `nil`.
187 */
188 func mapView(_ mapView: NGLMapView, didUpdate userLocation: NGLUserLocation?) {
189
190 }
191
192 /**
193 Tells the user that an attempt to locate the user's position failed.
194 @param mapView The map view that is tracking the user's location.
195 @param error An error object containing the reason why location tracking
196 failed.
197 */
198 func mapView(_ mapView: NGLMapView, didFailToLocateUserWithError error: Error) {
199
200 }
201
202
203 /**
204 Tells the user that the map view's user tracking mode has changed.
205 This method is called after the map view asynchronously changes to reflect the
206 new user tracking mode, for example by beginning to zoom or rotate.
207 private @param mapView The map view changed its tracking mode.
208 @param mode The new tracking mode.
209 @param animated Whether the change caused an animated effect on the map.
210 */
211 func mapView(_ mapView: NGLMapView, didChange mode: NGLUserTrackingMode, animated: Bool ) {
212
213 }
214
215 /**
216 Returns a screen coordinate at which to position the user location annotation.
217 This coordinate is relative to the map view's origin after applying the map view's
218 content insets.
219 When unimplemented, the user location annotation is aligned within the center of
220 the map view with respect to the content insets.
221 This method will override any values set by `NGLMapView.userLocationVerticalAlignment`
222 or `-[NGLMapView setUserLocationVerticalAlignment:animated:]`.
223 @param mapView The map view that is tracking the user's location.
224
225 Notes: We don't need to set the anchor point for now, so comment out this method first
226 */
227// func mapViewUserLocationAnchorPoint(_ mapView: NGLMapView ) -> CGPoint {
228//
229// }
230 /**
231 Tells the user that the map's location updates accuracy authorization has changed.
232
233 This method is called after the user changes location accuracy authorization when
234 requesting location permissions or in privacy settings.
235
236 @param mapView The map view that changed its location accuracy authorization.
237 @param manager The location manager reporting the update.
238
239 */
240 func mapView(_ apView: NGLMapView, didChangeLocationManagerAuthorization manager: NGLLocationManager) {
241
242 }
243
244 /**
245 Returns a view object to mark the given point annotation object on the map.
246 Implement this method to mark a point annotation with a view object. If you
247 want to mark a particular point annotation with a static image instead, omit
248 this method or have it return `nil` for that annotation, then implement
249 `-mapView:imageForAnnotation:` instead.
250 Annotation views are compatible with UIKit, Core Animation, and other Cocoa
251 Touch frameworks. On the other hand, static annotation images use less memory
252 and draw more quickly than annotation views.
253 The user location annotation view can also be customized via this method. When
254 `annotation` is an instance of `NGLUserLocation` (or equal to the map view's
255 `userLocation` property), return an instance of `NGLUserLocationAnnotationView`
256 (or a subclass thereof).
257 @param mapView The map view that requested the annotation view.
258 @param annotation The object representing the annotation that is about to be
259 displayed.
260 @return The view object to display for the given annotation or `nil` if you
261 want to display an annotation image instead.
262 */
263 func mapView(_ mapView: NGLMapView, viewFor annotation: NGLAnnotation) -> NGLAnnotationView? {
264 return nil
265 }
266
267}
268extension LocationStyleViewController: UITableViewDelegate, UITableViewDataSource {
269
270 func settingsTitlesForRaw(index: Int) -> String {
271 let type = typeList[index]
272 var title: String = ""
273 switch type {
274 case LocationType.HidePuckView :
275 title = "Hide puck view"
276 break
277 case LocationType.UpdateToFollowWithHeading:
278 title = "Update puck view to follow with heading"
279 break
280 case LocationType.UpdateToFollowWithCourse:
281 title = "Update puck view to follow with course"
282 break
283 case LocationType.UpdateToFollow:
284 title = "Update puck view to follow"
285 break
286 case LocationType.GetUserLocation:
287 title = "Get user location"
288 break
289 }
290 return title
291 }
292
293 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
294 return typeList.count
295 }
296 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
297 let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
298 cell.textLabel?.text = settingsTitlesForRaw(index: indexPath.row)
299 return cell
300 }
301 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
302 tableView.isHidden = true
303 let type = typeList[indexPath.row]
304 dismissSettings(type: type)
305 }
306
307 func dismissSettings(type: LocationType) {
308 dismiss(animated: true)
309 performeSettings(tyle: type)
310 }
311}


Let's break down the code:
Import Statements:
- The code begins with the import statements for the required frameworks, UIKit and Nbmap.
Enum Declaration:
- The LocationType enum defines different types of location settings, such as hiding the puck view, updating to follow the user's location, updating to follow with a heading, updating to follow with a course, and getting the user's location.
Class Declaration:
-
The
LocationStyleViewController
class is a subclass ofUIViewController
and serves as the main view controller for the location functionality. -
It declares a property
nbMapView
of typeNGLMapView
to display the map view and handles its setup and removal. -
It also declares a property button of type
UIButton
to show a settings button on the navigation bar. -
The class includes an array typeList that stores the different LocationType options.
-
The
viewDidLoad()
method initializes thenbMapView
and sets its delegate. It also sets up the settings button on the navigation bar. -
The
showSettings()
method is called when the settings button is tapped. It presents a table view controller to display location settings options. -
The
performSettings(type:)
method is called when a location setting is selected. It performs the corresponding action based on the selectedLocationType
.
Extensions:
-
The
LocationStyleViewController
extension implements theNGLMapViewDelegate
protocol, providing necessary delegate methods for the map view. -
The
mapView(_:didFinishLoading:)
method is called when the map finishes loading. It sets the initial camera position. -
Other delegate methods, such as mapViewWillStartLocatingUser, mapViewDidStopLocatingUser, and mapView(_:didChange:animated:), are implemented but are currently empty. They can be used to handle various events related to user location tracking.
-
The
mapView(styleForDefaultUserLocationAnnotationView:)
method customizes the appearance of the user location annotation view by setting properties such as puckFillColor, puckShadowColor, and haloFillColor. -
The
mapView(_:didUpdate:)
method is called when the user's location is updated. Currently, it is empty and can be used to perform actions based on the user's updated location. -
Other delegate methods, such as
mapView(_:didFailToLocateUserWithError:)
andmapView(_:didChangeLocationManagerAuthorization:)
, are implemented but are currently empty.
Additional Extensions:
-
The
LocationStyleViewController
extension implements theUITableViewDelegate
andUITableViewDataSource
protocols to handle the settings table view. -
The methods in these extensions populate the table view with the available location settings options and handle selection.
-
The
dismissSettings(type:)
method is called when a location setting is selected, and it dismisses the settings view controller and performs the corresponding action.
Overall, the code example provides a view controller that displays a map view, handles user location tracking, and allows the user to change the location tracking mode based on different settings.