I am using swift version 5.7.1 and Xcode 14.1 . I am creating Map Application with user location and it working fine .. But here is the problem , it giving warning ..
This method can cause UI unresponsiveness if invoked on the main thread. Instead, consider waiting for the -locationManagerDidChangeAuthorization:
callback and checking authorizationStatus
first..
On this line .. if CLLocationManager.locationServicesEnabled() {
I already added into main thread. but still same warning .. Here is the code ..
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
let mapView = MKMapView()
let manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
mapView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(mapView)
mapView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
manager.requestAlwaysAuthorization()
manager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
DispatchQueue.main.async {
self.manager.delegate = self
self.manager.desiredAccuracy = kCLLocationAccuracyBest
self.manager.startUpdatingLocation()
self.mapView.delegate = self
self.mapView.mapType = .standard
self.mapView.isZoomEnabled = true
self.mapView.isScrollEnabled = true
self.mapView.showsUserLocation = false
}
}
if let coor = mapView.userLocation.location?.coordinate{
mapView.setCenter(coor, animated: true)
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations
locations: [CLLocation]) {
guard let mylocation = manager.location else { return }
let myCoordinates: CLLocationCoordinate2D = mylocation.coordinate
mapView.mapType = MKMapType.standard
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let region = MKCoordinateRegion(center: myCoordinates, span: span)
mapView.setRegion(region, animated: true)
// comment pin object if showsUserLocation = true
let pin = MKPointAnnotation()
pin.coordinate = myCoordinates
pin.title = "You are here"
mapView.addAnnotation(pin)
}
}
Here is the screenshot ..
CodePudding user response:
The warning tells you that your should not call CLLocationManager.locationServicesEnabled()
at all, as it can take a long time and cause UI hiccups. Instead, you should implement the delegation function locationManagerDidChangeAuthorization(_:)
, check the authorizationStatus
and store the result somewhere, then use that stored value in your if
.
CodePudding user response:
Try this with locationManagerDidChangeAuthorization:
class Prova: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
let mapView = MKMapView()
let manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
mapView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(mapView)
mapView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
locationAuthorization()
}
func locationAuthorization(){
switch manager.authorizationStatus {
case .authorizedWhenInUse:
print("Authorized")
determineMyCurrentLocation()
case .denied:
break
case .authorizedAlways:
determineMyCurrentLocation()
case.notDetermined:
manager.requestAlwaysAuthorization()
manager.requestWhenInUseAuthorization()
sleep(2)
locationAuthorization()
default:
break
}
}
func determineMyCurrentLocation() {
print("determine current location")
if CLLocationManager.locationServicesEnabled() {
DispatchQueue.main.async {
self.manager.delegate = self
self.manager.desiredAccuracy = kCLLocationAccuracyBest
self.manager.startUpdatingLocation()
self.mapView.delegate = self
self.mapView.mapType = .standard
self.mapView.isZoomEnabled = true
self.mapView.isScrollEnabled = true
self.mapView.showsUserLocation = false // if you want to show default pin
}
}
if let coor = mapView.userLocation.location?.coordinate {
mapView.setCenter(coor, animated: true)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations
locations: [CLLocation]) {
guard let mylocation = manager.location else { return }
let myCoordinates: CLLocationCoordinate2D = mylocation.coordinate
mapView.mapType = MKMapType.standard
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let region = MKCoordinateRegion(center: myCoordinates, span: span)
mapView.setRegion(region, animated: true)
let pin = MKPointAnnotation()
pin.coordinate = myCoordinates
pin.title = "You are here"
mapView.addAnnotation(pin)
}
}