Search code examples
iosrx-swift

RxSwift set observable value in another observable next , not working


I am new to ios and rxswift. Trying create mvvm architecture for new app.

If I set observable isSuccess value before calling appStartNetwork.fetchApp() I can observe value. But when I set isSuccess value in fetchApp() on next, Observer in viewcontroller cant be triggered

Whats wrong?

ViewModel

class SplashViewModel {
var isSuccess = PublishSubject<Bool>()
var isLoading = PublishSubject<Bool>()

private let bag = DisposeBag()
func fetchAppStart() {
    self.isLoading.onNext(true)

    let appStartNetwork=NetworkProvider.shared.makeAppStartNetwork()
    appStartNetwork.fetchApp().subscribe(onNext: { [weak self] apiResult in
        switch apiResult{
        case let .success(response):
            //some codes
            self?.isLoading.onNext(false)
            self?.isSuccess.onNext(true)
            break
        case let .failure(errorContent):
            break
        }
        },onError:{ err in
            self.isLoading.onNext(false)
            self.isSuccess.onNext(false)
    }).disposed(by: bag)
}   }

View Controller

func getAppStart(){
    let splashVm=SplashViewModel()
    let disposeBag = DisposeBag()
    splashVm.isSuccess.subscribe(onNext: { (ok) in
        if(ok){
            print("splash success")
            self.navigateMain()
        }else{
            self.showAlert("splash fail")
        }

    },onError:{ err in
        self.showAlert(err.localizedDescription)
    }).disposed(by: disposeBag)
    splashVm.fetchAppStart()
 }

Solution

  • There are two problems here, both created by the same programming error, a wrong management of the dispose bag lifecycles.

    By creating your dispose bag within the scope of getAppStart, you are bounding its lifecycle to the function's life time. Meaning the dispose bag will dispose of its attached subscriptions when the function finishes.

    Moving the creating of both disposeBag and splashVm to the view controller's scope (outside the function), should fix your issue.

    let splashVm=SplashViewModel()
    let disposeBag = DisposeBag()
    
    func getAppStart(){
        splashVm.isSuccess.subscribe(onNext: { (ok) in
            if(ok){
                print("splash success")
                self.navigateMain()
            }else{
                self.showAlert("splash fail")
            }
    
        },onError:{ err in
            self.showAlert(err.localizedDescription)
        }).disposed(by: disposeBag)
        splashVm.fetchAppStart()
     }