使用CLLocation重复位置数据

时间:2016-12-12 13:52:58

标签: ios swift cllocationmanager

这是我正在使用的一个非常基本的支出...

import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
@IBOutlet weak var mapView: MKMapView!

// Call the locationManager class
let LocationManager = CLLocationManager()

// CoreData Delegate
let appDelegate = UIApplication.shared.delegate as! AppDelegate

override func viewDidLoad() {
    super.viewDidLoad()

    // Conform to Delegate Method
    self.LocationManager.delegate = self

    // Set required accuracy
    self.LocationManager.desiredAccuracy = kCLLocationAccuracyBest

    // Blue dot
    self.mapView.showsUserLocation = true

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// check location services active
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {

    // check location services
    switch CLLocationManager.authorizationStatus() {
    case .authorizedAlways:
        self.LocationManager.startUpdatingLocation()
    case .notDetermined:
        self.LocationManager.requestAlwaysAuthorization()
    case .authorizedWhenInUse, .restricted, .denied:
        let alertController = UIAlertController(
            title: "Background Location Access Disabled",
            message: "In order to work your location settings need to be set to 'Always'.",
            preferredStyle: .alert)

        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
        alertController.addAction(cancelAction)

        let openAction = UIAlertAction(title: "Open Settings", style: .default) { (action) in
            if let url = NSURL(string:UIApplicationOpenSettingsURLString) {
                UIApplication.shared.open(url as URL)
            }
        }
        alertController.addAction(openAction)

        self.present(alertController, animated: true, completion: nil)
    }

}

// Location delegate methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    print(locations)

    // get last location
    let location = locations.last

    print(location!.coordinate.latitude)

    // set region
    let region = MKCoordinateRegion(center: location!.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))

    // deploy region to map
    self.mapView.setRegion(region, animated: true)

    // Map to follow the user
    self.mapView.setUserTrackingMode(MKUserTrackingMode.follow, animated: true)

    // Show compass on map
    self.mapView.showsCompass = true

    // save the location data to CoreData
    //self.save(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)

    // end Location updating
    self.LocationManager.stopUpdatingLocation()


}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print("Errors: " + error.localizedDescription)
}


}

我的问题是func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]一次又一次地调用自己(初始加载时大约3次)...... 我使用的是.last,其中AFAIK用于取出该对象中的最后一个结果..它可能就是这样,因为断点在前两次打印后插入它只会返回1个结果... < / p>

经过高低搜索,我希望通过提问来得到结果......谢谢!

我的问题的控制台输出: console output

2 个答案:

答案 0 :(得分:1)

当您致电startUpdatingLocation()时,位置管理员会立即开始提供位置数据。第一个收到的位置可能偏离您的实际位置,因此请检查horizontalAccuracyverticalAccuracy属性,并关闭过于不准确的位置。

答案 1 :(得分:0)

看起来您只想获得一次性位置,如果是这样,请尝试以下代码:

// Use:
// at class level:
// var manager: LocationOneShotManager?
// in viewDidLoad:
//    manager = LocationOneShotManager()
//    manager!.fetchWithCompletion {location, error in
//        // fetch location or an error
//        if let loc = location {
//            println(location)
//        } else if let err = error {
//            println(err.localizedDescription)
//        }
//        self.manager = nil
//  }


import UIKit
import CoreLocation

// possible errors
enum OneShotLocationManagerErrors: Int {
    case AuthorizationDenied
    case AuthorizationNotDetermined
    case InvalidLocation
}

class LocationOneShotManager: NSObject, CLLocationManagerDelegate {

    // location manager
    private var locationManager: CLLocationManager?

    // destroy the manager
    deinit {
        locationManager?.delegate = nil
        locationManager = nil
    }

    typealias LocationClosure = ((location: CLLocation?, error: NSError?)->())
    private var didComplete: LocationClosure?

    // location manager returned, call didcomplete closure
    private func _didComplete(location: CLLocation?, error: NSError?) {
        locationManager?.stopUpdatingLocation()
        didComplete?(location: location, error: error)
        locationManager?.delegate = nil
        locationManager = nil
    }

    // location authorization status changed
    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {

        switch status {
        case .AuthorizedWhenInUse:
            self.locationManager!.startUpdatingLocation()
        case .Denied:
            _didComplete(nil, error: NSError(domain: self.classForCoder.description(),
                code: OneShotLocationManagerErrors.AuthorizationDenied.rawValue,
                userInfo: nil))
        default:
            break
        }
    }

    internal func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        _didComplete(nil, error: error)
    }

    internal func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations[0]
        _didComplete(location, error: nil)
    }

    // ask for location permissions, fetch 1 location, and return
    func fetchWithCompletion(completion: LocationClosure) {
        // store the completion closure
        didComplete = completion

        // fire the location manager
        locationManager = CLLocationManager()
        locationManager!.delegate = self

        // check for description key and ask permissions
        if (NSBundle.mainBundle().objectForInfoDictionaryKey("NSLocationWhenInUseUsageDescription") != nil) {
            locationManager!.requestWhenInUseAuthorization()
        } else if (NSBundle.mainBundle().objectForInfoDictionaryKey("NSLocationAlwaysUsageDescription") != nil) {
            locationManager!.requestAlwaysAuthorization()
        } else {
            fatalError("To use location in iOS8 you need to define either NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in the app bundle's Info.plist file")
        }
    }
}