didUpdateLocations 从未调用过
didUpdateLocations never called
我正在尝试获取用户的位置。为此,我在 info.plist 中设置了以下 属性 :
我还在我的 viewDidLoad 方法以及下面的函数中添加了以下代码。问题是 locationManager(manager, didUpdate....)
函数永远不会被调用,我也永远不会收到访问位置权限的提示,即使我已经删除并重新安装了该应用程序。我在我的 iPad 上测试这个,而不是在模拟器上。 didFailWithError 函数也永远不会被调用。
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("UPDATING")
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
let latitude = locValue.latitude
let longitude = locValue.longitude
latitudeText = "\(latitude)"
longitudeText = "\(longitude)"
if let a = latitudeText, b = longitudeText {
print(a)
print(b)
self.locationManager.stopUpdatingLocation()
if (userAlreadyExist()) {
dispatch_async(dispatch_get_main_queue(), {
//self.performSegueWithIdentifier("segueWhenLoggedIn", sender: self)
self.performSegueWithIdentifier("showCamera", sender: self)
// self.performSegueWithIdentifier("showTabBarController", sender: self)
})
}
else {
dispatch_async(dispatch_get_main_queue(), {
self.performSegueWithIdentifier("segueWhenLoggedOut", sender: self)
})
}
}
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print(error.localizedDescription)
}
编辑:
我添加了以下代码片段:
if CLLocationManager.locationServicesEnabled() {
print("yes")
}
else {
print("no")
}
它 returns 是的。我也检查了我的设备,locationServices 已启用,应用程序列在那里,但是所有其他应用程序旁边都有 "While Using"、"Never" 或 "Always",我的没有有什么写的。
你从哪里开始位置更新?例如:
//location manager
lazy var locationManager: CLLocationManager = {
var _locationManager = CLLocationManager()
_locationManager.delegate = self
_locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
_locationManager.activityType = . automotiveNavigation
_locationManager.distanceFilter = 10.0 // Movement threshold for new events
_locationManager.allowsBackgroundLocationUpdates = true // allow in background
return _locationManager
}()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation() // start location manager
}
这是一个有效的控制器代码:
设置自定义 iOS 目标属性也很重要。
将这两行添加到 Info.plist:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
//
// ViewController.swift
// LocationTest2
import UIKit
import CoreLocation
class ViewController: UIViewController {
//location manager
lazy var locationManager: CLLocationManager = {
var _locationManager = CLLocationManager()
_locationManager.delegate = self
_locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
_locationManager.activityType = . automotiveNavigation
_locationManager.distanceFilter = 10.0 // Movement threshold for new events
// _locationManager.allowsBackgroundLocationUpdates = true // allow in background
return _locationManager
}()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//allow location use
locationManager.requestAlwaysAuthorization()
print("did load")
print(locationManager)
//get current user location for startup
// if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
// }
}
}
// MARK: - CLLocationManagerDelegate
extension ViewController: CLLocationManagerDelegate {
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for location in locations {
print("**********************")
print("Long \(location.coordinate.longitude)")
print("Lati \(location.coordinate.latitude)")
print("Alt \(location.altitude)")
print("Sped \(location.speed)")
print("Accu \(location.horizontalAccuracy)")
print("**********************")
}
}
}
您应该在 didDetermineState
委托方法中调用 startUpdatingLocation()
if CLLocationManager.authorizationStatus() != .authorizedWhenInUse {
locationManager.requestWhenInUseAuthorization()
}else{
locationManager.startUpdatingLocation()
}
//稍后
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .authorizedWhenInUse:
manager.startUpdatingLocation()
break
case .authorizedAlways:
manager.startUpdatingLocation()
break
case .denied:
//handle denied
break
case .notDetermined:
manager.requestWhenInUseAuthorization()
break
default:
break
}
}
我四处寻找答案。这是唯一对我有用的东西:
将 didUpdateToLocation 的函数更改为:
func locationManager(_: CLLocationManager, didUpdateToLocation newLocation: CLLocation!,fromLocation oldLocation: CLLocation!) {
}
请注意 "as _: CLLocationManager" 的 细微变化 ,而不是 "manager: CLLocationManager"。
为我工作:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("locationManager update")
}
而不是这个
private func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("locationManager update")
}
还要确保您已将自定义位置设置为模拟器,因为默认情况下它将是 None ...
在模拟器中转到 Debug -> Location-> .
还应注意 locationManager:didFailWithError:如果模拟器中未设置位置,则会 运行,如您所料。
Swift 代码中此错误的一个非常微妙的原因。不要将委托调用 didUpdateLocations 定义为私有或文件私有。如果您这样做,位置管理器将无法找到或调用它。
好:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
差:
fileprivate func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
我使用 AppDelegate 作为 CLLocationManagerDelegate 而不是像大多数示例中那样 ViewController,这是我的代码
// AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var locationManager: CLLocationManager?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
...
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = rootViewController
self.window?.makeKeyAndVisible()
self.locationManager = CLLocationManager()
self.locationManager?.delegate = self
return true
}
}
我试图在调用退出事件时获取更新
// AppDelegate.swift
extension AppDelegate: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
if !CLLocationManager.locationServicesEnabled() {
return
}
let locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.allowsBackgroundLocationUpdates = true
locationManager.startUpdatingLocation()
return
}
}
但这没有用。相反,我不得不将 locationManager 的配置移动到 AppDelegate class,并且只在 AppDelegate 扩展中启动更新。
像这样
// AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var locationManager: CLLocationManager?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
...
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = rootViewController
self.window?.makeKeyAndVisible()
self.locationManager = CLLocationManager()
self.locationManager?.delegate = self
/* This was the catch, it needs to be here instead of inside extension */
self.locationManager?.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager?.distanceFilter = kCLDistanceFilterNone
self.locationManager?.allowsBackgroundLocationUpdates = true
/* */
return true
}
}
extension AppDelegate: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
if !CLLocationManager.locationServicesEnabled() {
return
}
/* Only do this here */
manager.startUpdatingLocation()
return
}
}
然后它开始工作,并发送持续的位置更新。我也在模拟器上测试过。
我正在尝试获取用户的位置。为此,我在 info.plist 中设置了以下 属性 :
我还在我的 viewDidLoad 方法以及下面的函数中添加了以下代码。问题是 locationManager(manager, didUpdate....)
函数永远不会被调用,我也永远不会收到访问位置权限的提示,即使我已经删除并重新安装了该应用程序。我在我的 iPad 上测试这个,而不是在模拟器上。 didFailWithError 函数也永远不会被调用。
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("UPDATING")
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
let latitude = locValue.latitude
let longitude = locValue.longitude
latitudeText = "\(latitude)"
longitudeText = "\(longitude)"
if let a = latitudeText, b = longitudeText {
print(a)
print(b)
self.locationManager.stopUpdatingLocation()
if (userAlreadyExist()) {
dispatch_async(dispatch_get_main_queue(), {
//self.performSegueWithIdentifier("segueWhenLoggedIn", sender: self)
self.performSegueWithIdentifier("showCamera", sender: self)
// self.performSegueWithIdentifier("showTabBarController", sender: self)
})
}
else {
dispatch_async(dispatch_get_main_queue(), {
self.performSegueWithIdentifier("segueWhenLoggedOut", sender: self)
})
}
}
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print(error.localizedDescription)
}
编辑:
我添加了以下代码片段:
if CLLocationManager.locationServicesEnabled() {
print("yes")
}
else {
print("no")
}
它 returns 是的。我也检查了我的设备,locationServices 已启用,应用程序列在那里,但是所有其他应用程序旁边都有 "While Using"、"Never" 或 "Always",我的没有有什么写的。
你从哪里开始位置更新?例如:
//location manager
lazy var locationManager: CLLocationManager = {
var _locationManager = CLLocationManager()
_locationManager.delegate = self
_locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
_locationManager.activityType = . automotiveNavigation
_locationManager.distanceFilter = 10.0 // Movement threshold for new events
_locationManager.allowsBackgroundLocationUpdates = true // allow in background
return _locationManager
}()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation() // start location manager
}
这是一个有效的控制器代码: 设置自定义 iOS 目标属性也很重要。
将这两行添加到 Info.plist:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
//
// ViewController.swift
// LocationTest2
import UIKit
import CoreLocation
class ViewController: UIViewController {
//location manager
lazy var locationManager: CLLocationManager = {
var _locationManager = CLLocationManager()
_locationManager.delegate = self
_locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
_locationManager.activityType = . automotiveNavigation
_locationManager.distanceFilter = 10.0 // Movement threshold for new events
// _locationManager.allowsBackgroundLocationUpdates = true // allow in background
return _locationManager
}()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//allow location use
locationManager.requestAlwaysAuthorization()
print("did load")
print(locationManager)
//get current user location for startup
// if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
// }
}
}
// MARK: - CLLocationManagerDelegate
extension ViewController: CLLocationManagerDelegate {
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for location in locations {
print("**********************")
print("Long \(location.coordinate.longitude)")
print("Lati \(location.coordinate.latitude)")
print("Alt \(location.altitude)")
print("Sped \(location.speed)")
print("Accu \(location.horizontalAccuracy)")
print("**********************")
}
}
}
您应该在 didDetermineState
委托方法中调用 startUpdatingLocation()
if CLLocationManager.authorizationStatus() != .authorizedWhenInUse {
locationManager.requestWhenInUseAuthorization()
}else{
locationManager.startUpdatingLocation()
}
//稍后
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .authorizedWhenInUse:
manager.startUpdatingLocation()
break
case .authorizedAlways:
manager.startUpdatingLocation()
break
case .denied:
//handle denied
break
case .notDetermined:
manager.requestWhenInUseAuthorization()
break
default:
break
}
}
我四处寻找答案。这是唯一对我有用的东西: 将 didUpdateToLocation 的函数更改为:
func locationManager(_: CLLocationManager, didUpdateToLocation newLocation: CLLocation!,fromLocation oldLocation: CLLocation!) {
}
请注意 "as _: CLLocationManager" 的 细微变化 ,而不是 "manager: CLLocationManager"。
为我工作:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("locationManager update")
}
而不是这个
private func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("locationManager update")
}
还要确保您已将自定义位置设置为模拟器,因为默认情况下它将是 None ... 在模拟器中转到 Debug -> Location-> .
还应注意 locationManager:didFailWithError:如果模拟器中未设置位置,则会 运行,如您所料。
Swift 代码中此错误的一个非常微妙的原因。不要将委托调用 didUpdateLocations 定义为私有或文件私有。如果您这样做,位置管理器将无法找到或调用它。
好:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
差:
fileprivate func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
我使用 AppDelegate 作为 CLLocationManagerDelegate 而不是像大多数示例中那样 ViewController,这是我的代码
// AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var locationManager: CLLocationManager?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
...
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = rootViewController
self.window?.makeKeyAndVisible()
self.locationManager = CLLocationManager()
self.locationManager?.delegate = self
return true
}
}
我试图在调用退出事件时获取更新
// AppDelegate.swift
extension AppDelegate: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
if !CLLocationManager.locationServicesEnabled() {
return
}
let locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.allowsBackgroundLocationUpdates = true
locationManager.startUpdatingLocation()
return
}
}
但这没有用。相反,我不得不将 locationManager 的配置移动到 AppDelegate class,并且只在 AppDelegate 扩展中启动更新。
像这样
// AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var locationManager: CLLocationManager?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
...
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = rootViewController
self.window?.makeKeyAndVisible()
self.locationManager = CLLocationManager()
self.locationManager?.delegate = self
/* This was the catch, it needs to be here instead of inside extension */
self.locationManager?.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager?.distanceFilter = kCLDistanceFilterNone
self.locationManager?.allowsBackgroundLocationUpdates = true
/* */
return true
}
}
extension AppDelegate: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
if !CLLocationManager.locationServicesEnabled() {
return
}
/* Only do this here */
manager.startUpdatingLocation()
return
}
}
然后它开始工作,并发送持续的位置更新。我也在模拟器上测试过。