【问题标题】:Repeating location data with CLLocation使用 CLLocation 重复位置数据
【发布时间】:2016-12-12 13:52:57
【问题描述】:

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

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 旨在提取该对象中的最后一个结果.. 它可能是,因为在前 2 个打印后插入断点,它只返回 1 个结果......

高低搜索后,希望能通过提问得到结果...谢谢!

我的问题的控制台输出:

【问题讨论】:

  • print(location!.coordinate.latitude) 打印了什么吗?
  • 确实有,只是没有将准确的输出粘贴出来

标签: ios swift cllocationmanager


【解决方案1】:

当您致电startUpdatingLocation() 时,位置管理器会立即开始传送位置数据。第一个传入的位置可能与您的实际位置相去甚远,因此请检查 horizontalAccuracyverticalAccuracy 属性并忽略那些太不准确的位置。

【讨论】:

  • 不幸的是,这些都返回相同的值......所以不能按它们过滤。
  • 您也可以查看位置对象中的时间戳
【解决方案2】:

看起来你只是想获得一个单一的位置,如果是这样,试试这个代码:

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

【讨论】:

    猜你喜欢
    • 2017-07-21
    • 2017-01-13
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多