2016-08-29 3 views
0

У меня есть список, который заполняется данными API. Таким образом, в основном процесс выглядит так:LocationManager location

Когда пользователь открывает приложение, что я делаю:

if CLLocationManager.locationServicesEnabled() { 
     locationManager.delegate = self 
     locationManager.desiredAccuracy = kCLLocationAccuracyBest 
     locationManager.distanceFilter = 20 
     locationManager.startUpdatingLocation() 
    } 

Тогда в моем func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) я называю API для получения данных.

Но проблема в том, что func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) может быть вызван до 5-6 раз, поэтому будет много вызовов API, и если я получу только одну позицию, то вероятность того, что я получу место, которое может быть далеко от пользователя.

Любые идеи о том, как решить эту проблему? Я в основном хочу лучшего места и сделать как можно меньше API-вызовов, предпочтительнее.

+1

Всего несколько мыслей: (a) дросселируйте свое приложение, чтобы сделать максимум * n * запросов в минуту; (b) каждое 'CLLocation' имеет свойство' horizontalAccuracy'. Если он слишком велик, не обращайте внимания на местоположение –

+0

Хороший комментарий @CodeDifferent, относительно идеи с 'horizontalAccuracy', что принимает самый низкий менеджер местоположения местоположения? Чтобы я знал, что я могу игнорировать. – user5855868

+0

Вам нужно поэкспериментировать, чтобы узнать. [Национальная медицинская библиотека] (https://communityhealthmaps.nlm.nih.gov/2014/07/07/how-accurate-is-the-gps-on-my-smart-phone-part-2/) цитирует исследование, в котором говорится, что точность iPhone 3G составляет около 8 метров. Это было в 2009 году. –

ответ

0

В принципе, если вы хотите избежать вызовы могут API на func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) вам необходимо рассмотреть некоторые элементы управления:

  • Создать интервал времени между полученным местах
  • «Улучшение» ваши horizontalAccuracy и distanceFilter значения

Имейте в виду, что вам всегда нужно избегать:

  • места Избегайте нильполугруппы
  • инвалидные места
  • инвалидные места
  • испорченный местонахождения
  • Закэшированные места (до начала locationManager)

Код Пример:

protocol MyLocationManagerDelegate { 
    func locationControllerDidUpdateLocation(location: CLLocation) 
} 

final class MyLocationManager: NSObject, CLLocationManagerDelegate { 

    var oldLocation: CLLocation? 
    let kTimeFilter = Double(10)     //avoid locations for each kTimeFilter seconds 
    let kValidDistanceToOldLocation = Double(100) //avoid location less than kValidDistanceToOldLocation meters 
    var startDate: NSDate? 
    var delegate: MyLocationManagerDelegate? 


    func isValidLocation(newLocation newLocation: CLLocation?, oldLocation: CLLocation?) -> Bool { 

     // avoid nil locations 
     if newLocation == nil { 
      return false 
     } 

     //avoid invalid locations 
     if newLocation!.coordinate.latitude == 0 || newLocation!.coordinate.longitude == 0 { 
      return false 
     } 

     //avoid invalid locations 
     if (newLocation!.horizontalAccuracy < 0){ 
      return false 
     } 

     if oldLocation != nil { 

      let distance = newLocation!.distanceFromLocation(oldLocation!) 

      if fabs(distance) < kValidDistanceToOldLocation { 
       return false 
      } 

      //avoid out-of-order location. 
      let secondsSinceLastPoint = newLocation!.timestamp.timeIntervalSinceDate(oldLocation!.timestamp) 
      if secondsSinceLastPoint < 0 || secondsSinceLastPoint < kTimeFilter { 
       return false 
      } 
     } 

     //avoid cached locations (before you start the locationManager) 
     let secondsSinceManagerStarted = newLocation!.timestamp.timeIntervalSinceDate(startDate!) 
     if secondsSinceManagerStarted < 0 { 
      return false 
     } 

     return true 
    } 

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

     let newLocation = locations.last 

     if isValidLocation(newLocation: newLocation, oldLocation:oldLocation) || oldLocation == nil { 
      self.delegate?.locationControllerDidUpdateLocation(newLocation!) 
      oldLocation = newLocation 
     } 

    } 

} 

class ViewController: UIViewController, MyLocationManagerDelegate { 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     let location = MyLocationManager() 
     location.delegate = self 

    } 

    func locationControllerDidUpdateLocation(location: CLLocation) { 
     //Api Call 
    } 

} 
Смежные вопросы