2017-07-10 4 views
0

Ich nehme das MVVM-Muster in meiner iOS-Anwendung. Ich zeige eine Reihe von Observablen als öffentliche Eigenschaften in meinem Ansichtsmodell an und binde die Benutzeroberfläche an diese Eigenschaften. Diese Observablen werden aus einer privaten verknüpfbaren Observablen erstellt.RxSwift: Verbinde mit verbindbaren Observable multiple Zeiten

Eine View-Controller-Klasse ruft dann die Methode "execute" auf, um die Netzwerkanforderung auszulösen. Wenn es jedoch aus irgendeinem Grund fehlschlägt, möchte ich in der Lage sein, "execute" erneut aufzurufen, aber das funktioniert nicht. Ich glaube, dass dies auf die Tatsache zurückzuführen ist, dass das verbindbare Observable abgeschlossen ist.

Wie kann ich dies erreichen, ohne jedes Mal das Ansichtsmodell neu erstellen zu müssen? Ich weiß, dass ich dies tun könnte, indem ich ein einfaches execute publish Thema zu den userDetailsObservable umwandelt, indem ich flatMap verwende, aber ich verlasse mich auf das onCompleted Ereignis für andere Funktionalität. Das onCompleted-Ereignis würde verloren gehen, wenn das Veröffentlichungsobjekt aktiv bleibt.

anschließbare beobachtbare Lösung

class ViewModel { 
    public var userName: Observable<String> { 
     self.userDetailsObservable.map { 
      return $0["username"] 
     } 
    } 

    public var address: Observable<String> { 
     self.userDetailsObservable.map { 
      return $0["address"] 
     } 
    } 

    public func execute() { 
     self.userDetailsObservable.connect() 
    } 

    private lazy var userDetailsObservable: ConnectableObservable<JSON> { 
     return Observable.create { observer in 
      // execute network request 
      // assume there is a json object and error object returned 
      if error != nil { 
       observer.onError(error) 
      } else { 
       observer.onNext(json) 
      } 
      observer.onCompleted() 
     }.publish() 
    } 
} 

Die FlatMap Lösung

dies das Netzwerk Anfrage zum Thema ausführen jedes Mal ein Ereignis gedrückt ausführen würde. (execute.onNext()). Das Problem hierbei ist, dass das onCompleted-Ereignis verloren geht, wenn wir ein veröffentlichtes Thema transformieren.

class ViewModel { 
    public var userName: Observable<String> { 
     self.userDetailsObservable.map { 
      return $0["username"] 
     } 
    } 

    public var address: Observable<String> { 
     self.userDetailsObservable.map { 
      return $0["address"] 
     } 
    } 

    public var execute: PublishSubject<Void>() 

    private lazy var userDetailsObservable: Observable<JSON> { 
     return self.execute.flatMapLatest { _ in 
      Observable.create { observer in 
       // execute network request 
       // assume there is a json object and error object returned 
       if error != nil { 
        observer.onError(error) 
       } else { 
        observer.onNext(json) 
       } 
       observer.onCompleted() 
      } 
     }.share() 
    } 

Antwort

1

sollten Sie catchError verwenden und einen Standardwert ("" zum Beispiel) zurück.

Sie müssen verhindern, dass die Observable entsorgt wird, wenn Sie einen Fehler von der API erhalten.