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