我希望使用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)"
}
}
答案 0 :(得分:52)
恕我直言,当您正在寻找的解决方案非常简单时,您的代码过于复杂。
我使用以下代码完成了它:
首先创建CLLocationManager
和请求授权
var locManager = CLLocationManager()
locManager.requestWhenInUseAuthorization()
然后检查用户是否允许授权。
var currentLocation: CLLocation!
if( CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
CLLocationManager.authorizationStatus() == .authorizedAlways){
currentLocation = locManager.location
}
使用它只是这样做
label1.text = "\(currentLocation.coordinate.longitude)"
label2.text = "\(currentLocation.coordinate.latitude)"
您将它们设置为label.text
的想法是正确的,但我能想到的唯一原因是用户未授予您权限,这就是您当前的位置数据为零的原因。
但是你需要调试并告诉我们。
此外CLLocationManagerDelegate
也不是必需的。
希望这会有所帮助。如果你有疑问,请随便询问。
答案 1 :(得分:24)
Swift 3:
首先,您需要设置容差以在info.plist
中接收用户的GPS。
使用随机字符串设置:NSLocationWhenInUseUsageDescription
。
和/或:NSLocationAlwaysUsageDescription
带有随机字符串。
然后:
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)
}
}
}
完成。
答案 2 :(得分:15)
尽管有其他建议,您应该使用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()
}
}
然后在视图中加载(或任何你需要获取当前位置的其他地方)运行:
Locator.shared.locate { result in
switch result {
case .Success(locator):
if let location = locator.location { /* ... */ }
case .Failure(error):
/* ... */
}
}
答案 3 :(得分:2)
在当前线程中,提出了一个没有委托的解决方案但是在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.
}
}
答案 4 :(得分:0)
在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)
}
}
答案 5 :(得分:0)
我同意上述凯文(Kevin)的观点,但是如果您希望为更简单的代码寻找更少的代码,则可以满足以下要求:
确保使用CLLocationManagerDelegate
迅速4:
在viewDidLoad中,您可以添加以下内容
locationManager.requestWhenInUseAuthorization()
if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse) || (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways) {
currentLocation = locationManager.location
print(currentLocation.coordinate.latitude)
print(currentLocation.coordinate.longitude)
}
}
对于第一个请求,一旦用户授予或拒绝许可,便响应:
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.
}
答案 6 :(得分:0)
确保将以下键添加到 Info.plist:
隐私 - 使用时的位置 使用说明 隐私 - 位置始终和使用时使用说明
创建用户类:
import Foundation
import CoreLocation
import MapKit
class User: NSObject, ObservableObject {
@Published var position = CLLocationCoordinate2D(latitude: 0.0, longitude: 0.0)
let manager = CLLocationManager()
override init() {
super.init()
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.requestLocation()
}
}
extension User: CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
print("Location services authorization request")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("User location updated")
print("Updated position: \(locations.first?.coordinate.latitude ?? 00)")
if let location = locations.first {
self.position = location.coordinate
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Failed to find user's location: \(error.localizedDescription)")
}
}