Best method for getting user location on button click

My intention is to find user location when he click on a button.

After some research I come up with 3 ways/methods to do that.

In each case, after determing the location, I show it on he map and print the coordinates ( latitude and longitude).

All 3 cases showed bellow work. But I can not figure out which one is the best/correct/fast.


THE 3 METHODS:

1) Method 1:

- using requestLocation()

- problem: it takes about 10 seconds to show location (quite slow)


2) Method 2 (could this be the best?)

- using CLLocationManagerDelegate (didUpdateLocations)


3) Method 3 (a little bit strange, but it works)

- using CLLocationManager().location?.coordinate




CODE:


1) Method 1:


import UIKit
import CoreLocation
import MapKit

class location1: UIViewController {
       let manager = CLLocationManager()
       @IBOutlet weak var Map: MKMapView!
  
       @IBOutlet weak var lbl_lat: UILabel!
       @IBOutlet weak var lbl_long: UILabel!
  
       @IBAction func btn_GetLocation(_ sender: Any) {
        manager.requestLocation()//get Location one time
  }
  override func viewDidLoad() {
       super.viewDidLoad()

  
       manager.requestAlwaysAuthorization()
       manager.requestWhenInUseAuthorization()
  
       if CLLocationManager.locationServicesEnabled(){
            manager.delegate = self
            manager.desiredAccuracy = kCLLocationAccuracyBest
  
       }else{
            print ("Err GPS")
       }
  
  }
}

extension location1: CLLocationManagerDelegate{
  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
       if let location = locations.first {
            print("Found user's location: \(location)", "lat =", location.coordinate.latitude," long = ",location.coordinate.longitude)
  
            lbl_lat.text = "My Lat:" + String(location.coordinate.latitude)
            lbl_long.text = "My Long:" + String(location.coordinate.longitude)
  
  
            let span = MKCoordinateSpanMake(0.0005, 0.0005)
            let mylocation = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
            let region = MKCoordinateRegionMake(mylocation, span)
            Map.setRegion(region, animated: true)
  
            //marker
            let marker1 = MKPointAnnotation()
            marker1.coordinate = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
            marker1.title = "My Position"
            Map.addAnnotation(marker1)
  
       }
  }
  
  func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
       print("Failed to find user's location: \(error.localizedDescription)")
  }
}







2) Method 2



import UIKit
import CoreLocation
import MapKit

class locatia2: UIViewController {
  
       @IBOutlet weak var Map: MKMapView!
       let manager = CLLocationManager()

  
       @IBOutlet weak var lbl_My_Longitude: UILabel!
       @IBOutlet weak var lbl_My_Latitude: UILabel!
  
       @IBAction func btn_get_my_location(_ sender: Any) {

            manager.startUpdatingLocation()
  
          }
       override func viewDidLoad() {
            super.viewDidLoad()


            manager.requestAlwaysAuthorization()
            manager.requestWhenInUseAuthorization()
  

            if CLLocationManager.locationServicesEnabled(){
                 manager.delegate = self
                 manager.desiredAccuracy = kCLLocationAccuracyBest
  
            }else{
                 print ("ErR GPS")
            }
  
       }
}

extension locatia2: CLLocationManagerDelegate{
 
  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
     if let location = locations.last {
            print("Found user's location: \(location)", "lat =", location.coordinate.latitude," long = ",location.coordinate.longitude)
  
            lbl_My_Latitude.text = "My Lat:" + String(location.coordinate.latitude)
            lbl_My_Longitude.text = "My Long:" + String(location.coordinate.longitude)
  
  
  
            let span = MKCoordinateSpanMake(0.0005, 0.0005)
            let mylocation = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
            let region = MKCoordinateRegionMake(mylocation, span)
            Map.setRegion(region, animated: true)
  
            //pun un marker
            let marker1 = MKPointAnnotation()
            marker1.coordinate = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
            marker1.title = "My Position"
            Map.addAnnotation(marker1)
  
            //close updating location
            manager.stopUpdatingLocation()
  
       }
  }
  
  func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
            print("Failed to find user's location: \(error.localizedDescription)")
            manager.stopUpdatingLocation()
  }

  
}




3) Method 3

import UIKit
import CoreLocation
import MapKit

class location3: UIViewController {
  @IBOutlet weak var lbl_long: UILabel!
  @IBOutlet weak var lbl_lat: UILabel!
  @IBOutlet weak var Map: MKMapView!
  let manager = CLLocationManager()

  @IBAction func btn_getPosition(_ sender: Any) {
       let SURSA = manager.location?.coordinate
       
       if let long = SURSA?.longitude{
            let long_sir = String(long)

            if let lat = SURSA?.latitude{
                      let lat_sir = String(lat)
                      lbl_lat.text = "My Lat: " + long_sir
                      lbl_long.text = "My Long:" + lat_sir

                      let span = MKCoordinateSpanMake(0.0005, 0.0005)
                      let mylocation = CLLocationCoordinate2DMake(SURSA!.latitude, SURSA!.longitude)
                      let region = MKCoordinateRegionMake(mylocation, span)
                      Map.setRegion(region, animated: true)

                      // marker
                      let marker1 = MKPointAnnotation()
                      marker1.coordinate = CLLocationCoordinate2DMake(SURSA!.latitude, SURSA!.longitude)
                      marker1.title = "My position"
                      Map.addAnnotation(marker1)
            }
       }
  }



  override func viewDidLoad() {
            super.viewDidLoad()

            manager.requestAlwaysAuthorization()
            manager.requestWhenInUseAuthorization()

            if CLLocationManager.locationServicesEnabled(){
            manager.delegate = self
            manager.desiredAccuracy = kCLLocationAccuracyBest
            }else{
                 print ("ErR GPS")
            }

  }

}
extension location3: CLLocationManagerDelegate{
            func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
                 print("Failed to find user's location: \(error.localizedDescription)")

                 manager.stopUpdatingLocation()
            }
}



Thanks in advance

Replies

I personnally usually use the first and find it works quite well.


Only difference :

I call

let newLocation = locations[locations.count - 1]

and not

let newLocation = locations.first

Thank you for the quick answer.

I also prefer the first method but the response comes after 10-12 seconds. On simulator I get a quick response but when tested on phone/tablet it takes longer.

I've tested on Iphone SE and Ipad Pro 9.7

Could you suggest me a method to reduce the response time for the first method?

Thanks

OK, I should have answered more precisely.


In fact, I do use startUpdating location when I opened the view and asked for authorization.


And ask stopUpdating as soon as I don't need.


Then I call

let newLocation = locations[locations.count - 1]

When I need to retrieve the new location


In your case, you could probably

- startUpdate when you open the window

- call let newLocation = locations[locations.count - 1] when you press button

- the question is when to stop udating (because it uses a lot of power)

- May be when you press the button, you could ask if user wants to continouously update ?

if not, next time you press button, you have to test if the user has asked not to continuously update ; then you should startUpdating again.


NOTE: this question should better be in Maps & location sub forum

I do not understand why do you think Method 3 as a little bit strange?

In method 3 - i don't use "manager.startUpdatingLocation()"...but is ok

So, you suggest that method 2 is the best?


In method 1, i don't use "startUpdating location", only "requestLocation()".

(from Apple documentation, about requestLocation() function: " ...This method returns immediately. Calling it causes the location manager to obtain a location fix (which may take several seconds) and call the delegate’s .............")...but, in my case, 10-12 sec to respond is too much.