How to get current longitude and latitude using CLLocationManager-Swift

后端 未结 6 515
囚心锁ツ
囚心锁ツ 2020-12-04 12:43

I want to get the current longitude and latitude of a location using Swift and display them via labels. I tried to do this but nothing displays on the labels.



        
相关标签:
6条回答
  • 2020-12-04 12:55

    In current thread a solution was proposed without delegate but in Xcode 9.1 testing in simulator it did not work, location was nil. This code worked:

     import UIKit
     import MapKit
    
    class ViewController: UIViewController, CLLocationManagerDelegate {
    
    var locationManager: CLLocationManager!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        if (CLLocationManager.locationServicesEnabled())
        {
            locationManager = CLLocationManager()
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.requestAlwaysAuthorization()
            locationManager.startUpdatingLocation()
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
    {
    
        let location = locations.last! as CLLocation
    
        /* you can use these values*/
        let lat = location.coordinate.latitude
        let long = location.coordinate.longitude
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    }
    
    0 讨论(0)
  • 2020-12-04 13:03

    Despite other advice you should use the CLLocationManagerDelegate to safely retrieve a location (without using it you may get null locations when the location manager doesn't have enough time to update). I strongly recommend wrapping the location manager code within a static shared helper (something along these lines):

    class Locator: NSObject, CLLocationManagerDelegate {
        enum Result <T> {
          case .Success(T)
          case .Failure(ErrorType)
        }
    
        static let shared: Locator = Locator()
    
        typealias Callback = (Result <Locator>) -> Void
    
        var requests: Array <Callback> = Array <Callback>()
    
        var location: CLLocation? { return sharedLocationManager.location  }
    
        lazy var sharedLocationManager: CLLocationManager = {
            let newLocationmanager = CLLocationManager()
            newLocationmanager.delegate = self
            // ...
            return newLocationmanager
        }()
    
        // MARK: - Authorization
    
        class func authorize() { shared.authorize() }
        func authorize() { sharedLocationManager.requestWhenInUseAuthorization() }
    
        // MARK: - Helpers
    
        func locate(callback: Callback) {
            self.requests.append(callback)
            sharedLocationManager.startUpdatingLocation()
        }
    
        func reset() {
            self.requests = Array <Callback>()
            sharedLocationManager.stopUpdatingLocation()
        }
    
        // MARK: - Delegate
    
        func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
            for request in self.requests { request(.Failure(error)) }
            self.reset()
        }
    
        func locationManager(manager: CLLocationManager, didUpdateLocations locations: Array <CLLocation>) {
            for request in self.requests { request(.Success(self)) }
            self.reset()
        }
    
    }
    

    Then in view did load (or anywhere else you need to get the current location) run:

    Locator.shared.locate { result in
      switch result {
      case .Success(locator):
        if let location = locator.location { /* ... */ }
      case .Failure(error):
        /* ... */
      }
    }
    
    0 讨论(0)
  • 2020-12-04 13:04

    In Swift

    import UIKit
    import CoreLocation
    
    class ViewController: UIViewController, CLLocationManagerDelegate {
    
        //Labels outlets
    
        @IBOutlet var localityTxtField: UITextField!
        @IBOutlet var postalCodeTxtField: UITextField!
        @IBOutlet var aAreaTxtField: UITextField!
        @IBOutlet var countryTxtField: UITextField!
    
        let locationManager = CLLocationManager()
    
        //View Didload
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
        }
    
         //Button Location
    
        @IBAction func findMyLocation(_ sender: AnyObject) {
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.requestWhenInUseAuthorization()
            locationManager.startUpdatingLocation()
        }
    
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in
    
                if (error != nil) {
                    print("Reverse geocoder failed with error" + (error?.localizedDescription)!)
                    return
                }
    
                if (placemarks?.count)! > 0 {
    
                    print("placemarks",placemarks!)
                    let pm = placemarks?[0]
                    self.displayLocationInfo(pm)
                } else {
                    print("Problem with the data received from geocoder")
                }
            })
        }
    
        func displayLocationInfo(_ placemark: CLPlacemark?) {
            if let containsPlacemark = placemark {
    
                print("your location is:-",containsPlacemark)
                //stop updating location to save battery life
                locationManager.stopUpdatingLocation()
                let locality = (containsPlacemark.locality != nil) ? containsPlacemark.locality : ""
                let postalCode = (containsPlacemark.postalCode != nil) ? containsPlacemark.postalCode : ""
                let administrativeArea = (containsPlacemark.administrativeArea != nil) ? containsPlacemark.administrativeArea : ""
                let country = (containsPlacemark.country != nil) ? containsPlacemark.country : ""
    
                localityTxtField.text = locality
                postalCodeTxtField.text = postalCode
                aAreaTxtField.text = administrativeArea
                countryTxtField.text = country
            }
    
        }
    
    
        func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
              print("Error while updating location " + error.localizedDescription)
        }
    }
    
    0 讨论(0)
  • 2020-12-04 13:06

    IMHO, you are over complicating your code when the solution you are looking is pretty simple.

    I have done it by using the following code:

    First create an instance of CLLocationManager and Request Authorization

    var locManager = CLLocationManager()
    locManager.requestWhenInUseAuthorization()
    

    then check if the user allowed authorization.

    var currentLocation: CLLocation!
    
    if 
       CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
       CLLocationManager.authorizationStatus() ==  .authorizedAlways
    {         
        currentLocation = locManager.location        
    }
    

    to use it just do this

    label1.text = "\(currentLocation.coordinate.longitude)"
    label2.text = "\(currentLocation.coordinate.latitude)"
    

    Your idea of setting them to the label.text is correct, however the only reason I can think of is that the user is not giving you permission and that is why your current Location data will be nil.

    However you would need to debug and tell us that. Also the CLLocationManagerDelegate is not necessary.

    Hopefully this helps. Ask away if you have doubts.

    0 讨论(0)
  • 2020-12-04 13:06

    For Swift 3:

    First you need to set allowance to receive User's GPS in the info.plist.

    Set: NSLocationWhenInUseUsageDescription with a random String. And/or: NSLocationAlwaysUsageDescription with a random String.

    Then:

    import UIKit
    import MapKit
    
    class ViewController: UIViewController {
    
        var locManager = CLLocationManager()
        var currentLocation: CLLocation!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            locManager.requestWhenInUseAuthorization()
    
            if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse ||
                CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways){
                guard let currentLocation = locManager.location else {
                    return
                }
                print(currentLocation.coordinate.latitude)
                print(currentLocation.coordinate.longitude)
            }
        }
    }
    

    Done.

    0 讨论(0)
  • 2020-12-04 13:06

    I agree with Kevin above, but if you're looking for less code for something simpler the following will suffice: Make sure to use the CLLocationManagerDelegate

    Swift 4:

    In viewDidLoad you can add the following

     locationManager.requestWhenInUseAuthorization()
    
    
    if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse) || (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways) {
    
                currentLocation = locationManager.location
                print(currentLocation.coordinate.latitude)
                print(currentLocation.coordinate.longitude)
    
            }
    
        }
    

    And for the first request respond once the user gives or denies permission:

     func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    
                if status == .authorizedWhenInUse {
    
                    locationManager.requestLocation()
                    currentLocation = locationManager.location
                    print(currentLocation.coordinate.latitude)
                    print(currentLocation.coordinate.longitude)
                    //Process location information and update.
    
        }
    
    0 讨论(0)
提交回复
热议问题