簡體   English   中英

didUpdateLocations 從未調用過

[英]didUpdateLocations never called

我正在嘗試獲取用戶的位置。 為此,我在 info.plist 中設置了以下屬性:

在此處輸入圖像描述

我還在我的 viewDidLoad 方法以及下面的 function 中添加了以下代碼。 問題是locationManager(manager, didUpdate....) function 永遠不會被調用,我也永遠不會收到訪問位置權限的提示,即使我已經刪除並重新安裝了該應用程序。 我在我的 iPad 上測試這個,而不是在模擬器上。 didFailWithError function 也永遠不會被調用。

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

它返回是。 我還檢查了我的設備,啟用了 locationServices,該應用程序列在那里,但是所有其他應用程序旁邊都寫有“使用時”、“從不”或“總是”,我的沒有寫任何東西。

你從哪里開始位置更新? 例如:

//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("**********************")


        }
    }

}

對我來說工作:

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 定義為 private 或 fileprivate。 如果您這樣做,位置管理器將無法找到或調用它。

好:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}

壞:

fileprivate func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    }

您應該在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 更改為:

func locationManager(_: CLLocationManager, didUpdateToLocation newLocation: CLLocation!,fromLocation oldLocation: CLLocation!) {
}

注意“as _: CLLocationManager”的細微變化,而不是“manager: CLLocationManager”。

在大多數示例中,我使用 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
  }
}

然后它開始工作,並發送持續的位置更新。 我也在模擬器上測試過。

確保在線程上調用了startUpdatingLocation方法,如下所示:

DispatchQueue.main.async { [weak self] in
    self?.locationManager.startUpdatingLocation()
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM