Search code examples
rx-swiftuiactivityindicatorviewreachability

trigger an api again once network goes off in RxSwift


Here is my code below. I need to call api multiple times until internet signal is on.

 buttonAction.do(onNext: { [weak self] in
                        
                          self?.activity.startAnimating()
                        
                              apiManager.callApi()
                            
                                .do(onNext: { [weak self] in
                                    
                                    self?.activity.stopAnimating()
                                    
                                },onError: { [weak self ] error in
                                    
                                    if let error = error as? NoNetwork {
                                        self?.activity.stopAnimating(errorInfo:error,presentationStyle:.alert)

                                        // here alert will be appear. On click ok button, need to trigger the API() again
                                    }
                                })
                .subscribe().disposed(by:bag)

Solution

  • Note that you didn't say how you want to deal with any other type of error so the code below just ignores them... Remove the filter if you want to show the alert for all errors.

    let error = PublishSubject<Error>()
    
    let retry = error
        .filter { $0 is NoNetwork }
        .map { $0.localizedDescription }
        .flatMapFirst(presentScene(animated: true, scene: { message in
            UIAlertController(title: "Error", message: message, preferredStyle: .alert)
                .scene { $0.connectOK() }
        }))
        .share()
    
    Observable.merge(buttonAction, retry)
        .subscribe(onNext: { [activity] in
            activity.startAnimating()
        })
        .disposed(by: bag)
    
    Observable.merge(buttonAction, retry)
        .flatMapFirst {
            apiManager.callApi()
                .catch { error.onNext($0); return .just(()) }
        }
        .subscribe(onNext: { [activity] in
            activity.stopAnimating()
        })
        .disposed(by: bag)
    

    The presentScene function comes from my CLE library. In this code activity is a standard UIActivityIndicatorView instead of whatever you are using.