Display a user's approximate location
A newer version of the Maps SDK is available
This page uses v6.4.1 of the Mapbox Maps SDK. A newer version of the SDK is available. Learn about the latest version, v11.7.0, in the Maps SDK documentation.
Displaying approximate user location is only available on iOS 14+. For more information about requesting location data from users, see Apple's location services guide.
import Mapbox
class ViewController: UIViewController, MGLMapViewDelegate {
var mapView: MGLMapView?
var preciseButton: UIButton?
override func viewDidLoad() {
super.viewDidLoad()
let mapView = MGLMapView(frame: view.bounds)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.delegate = self
mapView.showsUserLocation = true
self.mapView = mapView
view.addSubview(mapView)
}
/**
In order to enable the alert that requests temporary precise location,
please add the following key to your info.plist
`NSLocationTemporaryUsageDescriptionDictionary`
You must then add
`MGLAccuracyAuthorizationDescription`
as a key in the Privacy - Location Temporary Usage Description Dictionary
*/
@available(iOS 14, *)
func mapView(_ mapView: MGLMapView, didChangeLocationManagerAuthorization manager: MGLLocationManager) {
guard let accuracySetting = manager.accuracyAuthorization?() else { return }
if accuracySetting == .reducedAccuracy {
addPreciseButton()
} else {
removePreciseButton()
}
}
@available(iOS 14, *)
func addPreciseButton() {
let preciseButton = UIButton(frame: CGRect.zero)
preciseButton.setTitle("Turn Precise On", for: .normal)
preciseButton.backgroundColor = .gray
preciseButton.addTarget(self, action: #selector(requestTemporaryAuth), for: .touchDown)
self.view.addSubview(preciseButton)
self.preciseButton = preciseButton
// constraints
preciseButton.translatesAutoresizingMaskIntoConstraints = false
preciseButton.widthAnchor.constraint(equalToConstant: 150.0).isActive = true
preciseButton.heightAnchor.constraint(equalToConstant: 40.0).isActive = true
preciseButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 100.0).isActive = true
preciseButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
}
@available(iOS 14, *)
@objc private func requestTemporaryAuth() {
guard let mapView = self.mapView else { return }
let purposeKey = "MGLAccuracyAuthorizationDescription"
mapView.locationManager.requestTemporaryFullAccuracyAuthorization!(withPurposeKey: purposeKey)
}
private func removePreciseButton() {
guard let button = self.preciseButton else { return }
button.removeFromSuperview()
self.preciseButton = nil
}
}
#import "ViewController.h"
@import Mapbox;
@interface ViewController () <MGLMapViewDelegate>
@property (nonatomic) MGLMapView *mapView;
@property (nonatomic) UIButton *preciseButton;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
mapView.delegate = self;
mapView.showsUserLocation = YES;
self.mapView = mapView;
[self.view addSubview:mapView];
}
/**
In order to enable the alert that requests temporary precise location,
please add the following key to your info.plist
@c NSLocationTemporaryUsageDescriptionDictionary
You must then add
@c MGLAccuracyAuthorizationDescription
as a key in the Privacy - Location Temporary Usage Description Dictionary
*/
- (void)mapView:(MGLMapView *)mapView didChangeLocationManagerAuthorization:(id<MGLLocationManager>)manager {
if (@available(iOS 14, *)) {
if (manager.accuracyAuthorization == CLAccuracyAuthorizationReducedAccuracy) {
[self addPreciseButton];
} else {
[self removePreciseButton];
}
}
}
- (void)addPreciseButton {
UIButton *preciseButton = [UIButton buttonWithType:UIButtonTypeCustom];
[preciseButton setTitle:@"Turn Precise On" forState:UIControlStateNormal];
preciseButton.backgroundColor = UIColor.grayColor;
[preciseButton addTarget:self action:@selector(requestTemporaryAuth) forControlEvents:UIControlEventTouchDown];
self.preciseButton = preciseButton;
[self.view addSubview:preciseButton];
// constraints
[preciseButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[preciseButton.widthAnchor constraintEqualToConstant:150.0].active = YES;
[preciseButton.heightAnchor constraintEqualToConstant:40.0].active = YES;
[preciseButton.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:100.0].active = YES;
[preciseButton.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES;
}
- (void)requestTemporaryAuth {
if (self.mapView != nil) {
NSString *purposeKey = @"MGLAccuracyAuthorizationDescription";
if (@available(iOS 14, *)) {
[self.mapView.locationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKey:purposeKey];
}
}
}
- (void)removePreciseButton {
if (self.preciseButton != nil) {
[self.preciseButton removeFromSuperview];
self.preciseButton = nil;
}
}
@end