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

然后它开始工作,并发送持续的位置更新。我也在模拟器上测试过。