为什么这个Singleton Location Manager类返回一个nil位置?

时间:2018-06-04 08:03:14

标签: swift cllocationmanager

我正在尝试在我的项目中使用此blog中的LocationSingleton Class。我喜欢它的简单用法。

您只需致电:

即可开始更新位置
LocationSingleton.sharedInstance.startUpdatingLocation()

只需致电:

即可获取最后一个位置
LocationSingleton.sharedInstance.lastLocation

我的目的是启动位置服务,获取最后一个位置,以便我可以使用返回的位置从Firebase获取用户。

问题是,如果我在 lastLocation后直接致电startUpdatingLocation,则会返回nil

经过一些调试后,我发现原因是因为位置服务在设备上启动很慢,因此当调用lastLocation时,设备尚未获得该位置。 我想在记录lastLocation后立即执行下一个命令。我怎样才能做到这一点?

我想了解Protocol是如何使用的?

import UIKit
import CoreLocation

protocol LocationServiceDelegate {
    func locationDidUpdateToLocation(currentLocation: CLLocation)
    func locationUpdateDidFailWithError(error: NSError)
}

class LocationSingleton: NSObject,CLLocationManagerDelegate {
    var locationManager: CLLocationManager?
    var lastLocation: CLLocation?
    var delegate: LocationServiceDelegate?

    static let sharedInstance:LocationSingleton = {
        let instance = LocationSingleton()
        return instance
    }()

    override init() {
        super.init()
        self.locationManager = CLLocationManager()

        guard let locationManagers=self.locationManager else {
            return
        }

        if CLLocationManager.authorizationStatus() == .notDetermined {
            //locationManagers.requestAlwaysAuthorization()
            locationManagers.requestWhenInUseAuthorization()
        }

        if #available(iOS 9.0, *) {
            //            locationManagers.allowsBackgroundLocationUpdates = true
        } else {
            // Fallback on earlier versions
        }
        locationManagers.desiredAccuracy = kCLLocationAccuracyBest
        locationManagers.pausesLocationUpdatesAutomatically = false
        locationManagers.distanceFilter = 0.1
        locationManagers.delegate = self

    }


    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.last else {
            return
        }
        self.lastLocation = location
        updateLocation(currentLocation: location)

    }

    @nonobjc func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch status {
        case .notDetermined:
            locationManager?.requestWhenInUseAuthorization()
            break
        case .authorizedWhenInUse:
            locationManager?.startUpdatingLocation()
            break
        case .authorizedAlways:
            locationManager?.startUpdatingLocation()
            break
        case .restricted:
            // restricted by e.g. parental controls. User can't enable Location Services
            break
        case .denied:
            // user denied your app access to Location Services, but can grant access from Settings.app
            break
        default:
            break
        }
    }



    // Private function
    private func updateLocation(currentLocation: CLLocation){

        guard let delegate = self.delegate else {
            return
        }

        delegate.locationDidUpdateToLocation(currentLocation: currentLocation)
    }

    private func updateLocationDidFailWithError(error: NSError) {

        guard let delegate = self.delegate else {
            return
        }

        delegate.locationUpdateDidFailWithError(error: error)
    }

    func startUpdatingLocation() {
        print("Starting Location Updates")
        self.locationManager?.startUpdatingLocation()
        //        self.locationManager?.startMonitoringSignificantLocationChanges()
    }

    func stopUpdatingLocation() {
        print("Stop Location Updates")
        self.locationManager?.stopUpdatingLocation()
    }

    func startMonitoringSignificantLocationChanges() {
        self.locationManager?.startMonitoringSignificantLocationChanges()
    }

}

1 个答案:

答案 0 :(得分:2)

位置管理器以异步方式工作,并提供委托方法来获取结果。

在您的班级中采用LocationServiceDelegate,实施委托方法并设置代理,例如viewDidLoad

func locationDidUpdateToLocation(currentLocation: CLLocation)
{
    print(LocationSingleton.sharedInstance.lastLocation)
}

func locationUpdateDidFailWithError(error: NSError)
{
    print(error)
}

func viewDidLoad()
    super viewDidLoad()

    let locationSingleton = LocationSingleton.sharedInstance
    locationSingleton.delegate = self
    locationSingleton.startUpdatingLocation()
}

检测到位置时,会调用其中一个委托方法