2016-08-29 4 views
0

Ich habe eine Liste, die mit Daten von einer API aufgefüllt wird. Also im Grunde ist das Verfahren wie folgt aus:LocationManager Standorte

Wenn der Benutzer die Anwendung öffnet ich tun:

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

Da ist in meinem func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) nenne ich die API-Daten zu erhalten.

Aber das Problem ist, dass func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) bis zu 5-6 mal manchmal aufgerufen werden kann, so wird es viele API-Aufrufe geben und wenn ich nur eine Position bekomme, ist die Chance groß, dass ich einen Standort, der weit weg sein kann vom Benutzer.

Irgendwelche Ideen, wie Sie dieses Problem lösen können? Ich möchte grundsätzlich den besten Standort und mache so wenige API-Aufrufe wie möglich, vorzugsweise einen.

+1

Nur ein paar Gedanken: (a) drosseln Sie Ihre eigene App, um maximal * n * Anfragen pro Minute zu machen; (b) jeder 'CLLocation' hat eine Eigenschaft' horizontalAccuracy'. Wenn es zu groß ist, ignorieren Sie den Standort –

+0

Guten Kommentar @CodeDifferent, in Bezug auf die Idee mit 'horizontalAccuracy' was ist die niedrigste Genauigkeit Standortmanager akzeptiert? Damit ich weiß was ich ignorieren kann. – user5855868

+0

Sie müssen experimentieren, um herauszufinden. [Die National Library of Medicine] (https://communityhealthmaps.nlm.nih.gov/2014/07/07/how-accurate-is-the-gps-on-my-smart-phone-part-2/) zitiert Eine Studie, die iPhone 3G Genauigkeit sagt, ist etwa 8 Meter. Das war 2009. –

Antwort

0

Grundsätzlich, wenn Sie Anrufe können API auf func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) wollen vermeiden Sie müssen einige Kontrollen berücksichtigen:

  • Erstellen Sie ein Zeitintervall zwischen den empfangenen Stellen
  • "Improve" Ihre horizontalAccuracy und distanceFilter Werte

Denken Sie daran, dass Sie immer vermeiden müssen:

  • Vermeiden nil Stellen
  • Ungültige Standorte
  • Ungültige Standorte
  • Out-of-Order-Lage
  • Cached Standorte

Codebeispiel (bevor Sie die Locationmanager starten):

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 
    } 

}