J'adopte le modèle MVVM dans mon application iOS. J'expose une gamme d'Observables en tant que propriétés publiques dans mon modèle de vue et lie l'interface utilisateur à ces propriétés. Ces Observables sont créés à partir d'un observable connectable privé.RxSwift: Connexion à des multipôles observables connectables
Une classe de contrôleur de vue appelle ensuite la méthode "execute" pour déclencher la requête réseau. Cependant, si cela échoue pour quelque raison que ce soit, j'aimerais pouvoir rappeler "execute" mais cela ne fonctionne pas. Je crois que cela est dû au fait que l'observable connectable est terminée.
Comment puis-je y parvenir sans avoir à recréer le modèle de vue à chaque fois? Je sais que je pourrais le faire en transformant un simple objet de publication execute en userDetailsObservable en utilisant flatMap mais je compte sur l'événement onCompleted pour d'autres fonctionnalités. L'événement onCompleted sera perdu car le sujet de publication reste actif.
Connectable Observable Solution
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()
}
}
La solution FlatMap
Cette exécuterait la demande du réseau chaque fois qu'un événement est poussé sur l'exécution sujet. (execute.onNext()). Le problème ici est que l'événement onCompleted est perdu car nous transformons un sujet de publication.
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()
}