All the questions on stack overflow that are similar to this seem to be for Java and Android.
I have the following code using a MKMapView control.
override func viewDidLoad() {
super.viewDidLoad()
mapView.showsUserLocation = true
mapView.setUserTrackingMode(.followWithHeading, animated: true)
let locationCoordinate = CLLocationCoordinate2D(latitude: mapView.userLocation.coordinate.latitude, longitude: mapView.userLocation.coordinate.longitude)
currentLocationCoordinateRegion = MKCoordinateRegion(center: locationCoordinate, latitudinalMeters: 200, longitudinalMeters: 200)
mapView.setRegion(currentLocationCoordinateRegion, animated: true)
print("latitude:", mapView.userLocation.coordinate.latitude, "longitude:", mapView.userLocation.coordinate.longitude)
}
I am using an actual device, so the map view should show my current location and the print statement should print my current location, but instead I see blue on the map view, and the print results show a latitude of 0.0 and a longitude of 0.0 in the debug window:
latitude: 0.0 longitude: 0.0
Why is it doing this and what should I do to fix this?
I also have a bar button item on a toolbar with the following code:
@IBAction func actionShow(_ sender: UIBarButtonItem) {
print("latitude:", mapView.userLocation.coordinate.latitude, "longitude:", mapView.userLocation.coordinate.longitude)
let locationCoordinate = CLLocationCoordinate2D(latitude: mapView.userLocation.coordinate.latitude, longitude: mapView.userLocation.coordinate.longitude)
currentLocationCoordinateRegion = MKCoordinateRegion(center: locationCoordinate, latitudinalMeters: 200, longitudinalMeters: 200)
mapView.setRegion(currentLocationCoordinateRegion, animated: true)
}
That yields the same results.
You must ask for permission to access user location, this is the first action you perform in viewDidLoad
and then proceed to show user location once you have the permission, following UIViewController will get you going
class ViewController: UIViewController {
@IBOutlet var mapView: MKMapView!
var locationManager: CLLocationManager?
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
mapView.setUserTrackingMode(.followWithHeading, animated: true)
self.checkLocationAuthorization()
}
func checkLocationAuthorization(authorizationStatus: CLAuthorizationStatus? = nil) {
switch (authorizationStatus ?? CLLocationManager.authorizationStatus()) {
case .authorizedAlways, .authorizedWhenInUse:
mapView.showsUserLocation = true
case .notDetermined:
if locationManager == nil {
locationManager = CLLocationManager()
locationManager!.delegate = self
}
locationManager!.requestWhenInUseAuthorization()
default:
print("Location Servies: Denied / Restricted")
}
}
}
extension ViewController: MKMapViewDelegate, CLLocationManagerDelegate {
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
let region = MKCoordinateRegion(center: userLocation.coordinate, latitudinalMeters: 200, longitudinalMeters: 200)
mapView.setRegion(region, animated: true)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
self.checkLocationAuthorization(authorizationStatus: status)
}
}
You must also include following properties in Info.plist
, without these locationManager
will just not proceed to request authorization.
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Message for AlwaysAndWhenInUseUsageDescription</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Message for AlwaysUsageDescription</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Message for WhenInUseUsageDescription</string>