Reputation:
I am trying to display user current location when user granted to access user current location and also drop pin into current location of the user. I am using Xcode 15.3 and Swift version 5.10 . I have added the require filed into info.plit and define necessary function for it with outlet as well. But the problem is I got following warning into console ..
This method can cause UI unresponsiveness if invoked on the main thread. Instead, consider waiting for the -locationManagerDidChangeAuthorization:
callback and checking authorizationStatus
first.
This is error message into console and showing just Uk map into app when I run the app but I am expecting to show user current location with pin.
Error Domain=kCLErrorDomain Code=1 "(null)"
Here is the screenshot for info.plit ..
Here is the screenshot when I run the app..
Here is the code ..
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var myMap: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
if (CLLocationManager.locationServicesEnabled()) {
locationManager.requestLocation()
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let userLocation = locations.first {
manager.stopUpdatingLocation()
let coordinate = CLLocationCoordinate2D(latitude: locationManager.location?.coordinate.latitude ?? 0.0, longitude: locationManager.location?.coordinate.longitude ?? 0.0)
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let region = MKCoordinateRegion(center: coordinate, span: span)
myMap.setRegion(region, animated: true)
let myPin = MKPointAnnotation()
myPin.coordinate = coordinate
myPin.title = "Hey There"
myPin.subtitle = "I am here"
myMap.addAnnotation(myPin)
}
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch manager.authorizationStatus {
case .authorizedAlways:
return
case .authorizedWhenInUse:
return
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
locationManager.requestWhenInUseAuthorization()
case .denied:
return
@unknown default:
locationManager.requestWhenInUseAuthorization()
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) {
print(error)
}
}
Upvotes: 1
Views: 109
Reputation: 8866
Make sure providing both NSLocationAlwaysAndWhenInUseUsageDescription
and NSLocationWhenInUseUsageDescription
keys in Info plist file.
In viewDidLoad
, you're able to fetch the current authorizationStatus
by:
switch locationManager.authorizationStatus {
case .notDetermined:
//Request the first time
locationManager.requestAlwaysAuthorization()
case .denied, .restricted:
//TODO: Handle when user denied location permission
//Force to open location permission in Setting for example
break
default:
break
}
Then didChangeAuthorization
will trigger startUpdatingLocation
because from now on, it's ready to work.
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
if manager.authorizationStatus == .authorizedWhenInUse || manager.authorizationStatus == .authorizedAlways {
locationManager.startUpdatingLocation()
}
}
You can keep stopUpdatingLocation
whenever the current location is focused like above depend on the requirement, or put it on deinit
/viewDidDisappear
.
Upvotes: 0