2017-10-07 20 views
1

J'ai un MapViewModel pour mon MapViewController.Observables de chaîne dans ViewModel pour l'extraction mais laisser en tant que propriétés indépendantes

J'ai un MapObjectService avec une fonction fetchMapObjects(currentLocation: CLLocation) qui retourne un Observable<MapObjects>

Dans le MapViewModel je:

var currentLocation: Observable<CLLocation?> 
var mapObjects: Observable<MapObjects> 

je peux initialiser l'emplacement actuel comme celui-ci:

currentLocation = locationManager.rx.didUpdateLocations.map({ locations in 
     return locations.filter() { loc in 
      return loc.horizontalAccuracy < 20 
      }.first 
    }) 

Comment puis-je initier efficacement les deux propriétés de sorte que le fetchMapObjects() utilise le currentLocation pour définir le mapObjects propriété?

Mon plan consiste à lier ces propriétés à mapView dans MapViewController pour afficher les objets de la carte comme des broches et l'emplacement actuel.

Merci!

Répondre

0

Vous pouvez le faire:

currentLocation = locationManager.rx.didUpdateLocations.map({ locations in 
    return locations.filter() { loc in 
     return loc.horizontalAccuracy < 20 
    }.first 
}) 

mapObjects = currentLocation.flatMap { loc in 
    return MapObjectService.fetchMapObjects(currentLocation: loc) 
} 
2

Vous pouvez définir mapObjects comme une continuation du flux currentLocation:

Quelque chose comme ceci:

currentLocation = locationManager.rx.didUpdateLocations.map { locations in 
    return locations.first(where: { location -> Bool in 
     return location.horizontalAccuracy < 20 
    }) 
} 

mapObjects = currentLocation.flatMapLatest { location -> Observable<MapObjects> in 
    guard let location = location else { 
     return Observable<String>.empty() 
    } 
    return fetchMapObjects(currentLocation: location) 
} 

De cette façon, chaque fois le currentLocation observable émet un emplacement où il sera utilisé pour le fetchMapObjects appel.

J'ai utilisé ici flatMapLatest au lieu de flatMap afin de rejeter tous les appels précédents au fetchMapObjects si un nouvel emplacement est émis avant la fin de l'appel.

Vous pouvez également définir un filtrage pour currentLocation avant le flatMapLatest au cas où vous souhaitez ignorer certains d'entre eux, par ex. lorsque la distance est trop courte par rapport à la précédente.

Maintenant, vous pouvez simplement vous abonner à votre mapObjects observable et gérer tout MapObjects qui sont émis.

mapObjects.subscribe(onNext: { objects in 
    // handle mapObjects here 
}) 
+0

Merci pour la bonne explication. C'est ce que j'ai fait! – MayNotBe

+0

@MayNotBe vous êtes les bienvenus! Cependant, juste pour être juste, joern a répondu à la question avant moi et a fondamentalement dit la même chose que moi :) Donc, si vous voulez, vous pouvez marquer sa réponse au lieu de la mienne. Je vais prendre un upvote peut-être? ;) – iska

+0

Merci @iska! Franchement, votre réponse est meilleure que la mienne et mérite au moins une autre surenchère. – joern