如何使用CLLocationManager-Swift获取当前经度和纬度

时间:2022-05-20 16:54:49

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.

我想使用Swift获取位置的当前经度和纬度,并通过标签显示它们。我尝试这样做,但标签上没有显示任何内容。

import UIKit
    import CoreLocation
    class ViewController: UIViewController, CLLocationManagerDelegate{

    @IBOutlet weak var longitude: UILabel!
    @IBOutlet weak var latitude: UILabel!
    let locationManager = CLLocationManager()
    override func viewDidLoad() {
            super.viewDidLoad()
            if (CLLocationManager.locationServicesEnabled()) {
                        locationManager.delegate = self
                        locationManager.desiredAccuracy = kCLLocationAccuracyBest
                        locationManager.requestWhenInUseAuthorization()
                        locationManager.startUpdatingLocation()
                    } else {
                        println("Location services are not enabled");
                    }
                }
        // MARK: - CoreLocation Delegate Methods
            func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
                locationManager.stopUpdatingLocation()
                removeLoadingView()
                if ((error) != nil) {
                    print(error)
                }
            }

            func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
                var locationArray = locations as NSArray
                var locationObj = locationArray.lastObject as CLLocation
                var coord = locationObj.coordinate
                longitude.text = coord.longitude
                latitude.text = coord.latitude
                longitude.text = "\(coord.longitude)"
               latitude.text = "\(coord.latitude)"
            }
    }

6 个解决方案

#1


37  

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

首先创建CLLocationManager和请求授权的实例

    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.

您将它们设置为label.text的想法是正确的,但我能想到的唯一原因是用户没有给您许可,这就是您当前的位置数据为零的原因。

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

但是你需要调试并告诉我们。此外,CLLocationManagerDelegate不是必需的。

Hopefully this helps. Ask away if you have doubts.

希望这会有所帮助。如果你有疑问,请随便询问。

#2


16  

For Swift 3:

对于Swift 3:

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

首先,您需要设置容差以在info.plist中接收用户的GPS。

如何使用CLLocationManager-Swift获取当前经度和纬度

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

设置:带有随机字符串的NSLocationWhenInUseUsageDescription。和/或:带有随机字符串的NSLocationAlwaysUsageDescription。

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){
            currentLocation = locManager.location
            print(currentLocation.coordinate.latitude)
            print(currentLocation.coordinate.longitude)
        }
    }
}

Done.

完成。

#3


14  

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):

尽管有其他建议,您应该使用CLLocationManagerDelegate安全地检索位置(不使用它,当位置管理器没有足够的时间来更新时,您可能会获得空位置)。我强烈建议将位置管理器代码包装在静态共享帮助器中(沿着这些行):

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):
    /* ... */
  }
}

#4


1  

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:

在当前的线程中,提出了一个没有委托的解决方案但是在Xcode 9.1中在模拟器中测试它不起作用,位置是零。这段代码有效:

 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.
}


}

#5


0  

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)
    }
}

#6


0  

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

我同意上面的Kevin,但是如果你正在寻找更简单的代码,那么下面就足够了:确保使用CLLocationManagerDelegate

Swift 4:

斯威夫特4:

In viewDidLoad you can add the following

在viewDidLoad中,您可以添加以下内容

 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.

    }

#1


37  

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

首先创建CLLocationManager和请求授权的实例

    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.

您将它们设置为label.text的想法是正确的,但我能想到的唯一原因是用户没有给您许可,这就是您当前的位置数据为零的原因。

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

但是你需要调试并告诉我们。此外,CLLocationManagerDelegate不是必需的。

Hopefully this helps. Ask away if you have doubts.

希望这会有所帮助。如果你有疑问,请随便询问。

#2


16  

For Swift 3:

对于Swift 3:

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

首先,您需要设置容差以在info.plist中接收用户的GPS。

如何使用CLLocationManager-Swift获取当前经度和纬度

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

设置:带有随机字符串的NSLocationWhenInUseUsageDescription。和/或:带有随机字符串的NSLocationAlwaysUsageDescription。

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){
            currentLocation = locManager.location
            print(currentLocation.coordinate.latitude)
            print(currentLocation.coordinate.longitude)
        }
    }
}

Done.

完成。

#3


14  

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):

尽管有其他建议,您应该使用CLLocationManagerDelegate安全地检索位置(不使用它,当位置管理器没有足够的时间来更新时,您可能会获得空位置)。我强烈建议将位置管理器代码包装在静态共享帮助器中(沿着这些行):

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):
    /* ... */
  }
}

#4


1  

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:

在当前的线程中,提出了一个没有委托的解决方案但是在Xcode 9.1中在模拟器中测试它不起作用,位置是零。这段代码有效:

 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.
}


}

#5


0  

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)
    }
}

#6


0  

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

我同意上面的Kevin,但是如果你正在寻找更简单的代码,那么下面就足够了:确保使用CLLocationManagerDelegate

Swift 4:

斯威夫特4:

In viewDidLoad you can add the following

在viewDidLoad中,您可以添加以下内容

 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.

    }