2017-06-12 2 views
2

J'ai une méthode 'getProducts' dans mon modèle de vue:état du réseau RxSwift observable

struct MyViewModel { 
    func getProducts(categoryId: Int) -> Observable<[Product]> { 
     return api.products(categoryId: categoryId) 
    } 
    var isRunning: Observable <Bool> = { 
     ... 
    } 
} 

api.products est une variable privée qui utilise URLSession rx extension: session.rx.data(...) en arrière-plan.

Je voudrais avoir un observateur isRunning dans mon modèle de vue auquel je pourrais m'abonner pour savoir s'il s'agit d'une requête réseau.

Est-ce quelque chose que je pourrais faire sans apporter de modifications à ma classe d'api? Je suis nouveau dans la programmation réactive donc toute aide serait appréciée.

Merci.

Répondre

2

Voici une solution utilisant une classe d'aide écrite par les auteurs de RxSwift au RxSwift Examples appelée ActivityIndicator.

Les idées est simple

struct MyViewModel { 
    /// 1. Create an instance of ActivityIndicator in your viewModel. You can make it private 
    private let activityIndicator = ActivityIndicator() 

    /// 2. Make public access to observable part of ActivityIndicator as you already mentioned in your question 
    var isRunning: Observable<Bool> { 
     return activityIndicator.asObservable() 
    } 

    func getProducts(categoryId: Int) -> Observable<[Product]> { 
     return api.products(categoryId: categoryId) 
      .trackActivity(activityIndicator) /// 3. Call trackActivity method in your observable network call 
    } 
} 

En ViewController vous pouvez maintenant lié abonner à la propriété IsRunning. Par exemple:

viewModel.isLoading.subscribe(onNext: { loading in 
     print(loading) 
    }).disposed(by: bag) 
+0

Que dois-je importer pour pouvoir appeler trackActivity sur mon observable? – Greg

+0

Le fichier source de ActivityIndicator (le lien est posté dans ma réponse) contient déjà la méthode trackAcyivity dans le cadre de l'extension ObservableConvertibleType – Nimble

+0

Merci, c'est ce que je cherchais. – Greg