Search code examples
swiftalamofirerx-swift

call func in Asynchronous requests chaining RxSwift and Alamofire


I'm a begginer with RxSwift and this is my issue, my app must do a 3 requests, the 3 are gets, my work team suggests me use a flatmap to do this a three request in row, but I don't know how I should use flatmap.

these are my requests

public func login(param: [String:String]) -> Observable<messageModel>{
        return Observable.create { observer -> Disposable in
            self.alamoFireManager!.request(self.urlServer!+endPoints.login.login, method: .post, parameters: param, encoding: URLEncoding.default, headers: nil, interceptor: nil).responseDecodable { (res: DataResponse<messageModel,AFError>) in
                if let error = res.error {
                    observer.onError(error)
                } else if let valueEntitie = res.value {
                    observer.onNext(valueEntitie)
                }
                observer.onCompleted()
            }
            return Disposables.create()
        }
    }


public func me()  -> Observable<meModel>{
        return Observable.create { observer -> Disposable in
            self.alamoFireManager!.request(self.urlServer!+endPoints.login.me, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil, interceptor: nil).responseDecodable { (res: DataResponse<meModel,AFError>) in
                if let error = res.error {
                    observer.onError(error)
                } else if let valueEntitie = res.value {
                    observer.onNext(valueEntitie)
                }
                observer.onCompleted()
            }
            return Disposables.create()
        }
    }


public func entitie(entityId: String) -> Observable<entitieModel>{
        return Observable.create { observer -> Disposable in
            self.alamoFireManager!.request(self.urlServer!+endPoints.login.entities+"/"+entityId, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil, interceptor: nil).responseDecodable { (res: DataResponse<entitieModel,AFError>) in
                if let error = res.error {
                    observer.onError(error)
                } else if let valueEntitie = res.value {
                    observer.onNext(valueEntitie)
                }
                observer.onCompleted()
            }
            return Disposables.create()
        }
    }

the first endpoint is login with its parameters, then me, function me response a id, this id its necessary for the third request, that is entitie.

I'm doing the flatmap as this way.

networkManagerShareCore.share.login(param: param)
                .flatMap { resMessageModel in
                    //saveData(resMessageModel)
                    networkManagerShareCore.share.me()
                        .flatMap { resMeModel in
                         //saveData(resMessageModel)
                         networkManagerShareCore.share.entitie(entityId: "\(resModelMe.data.personId!)")
                    }
            }.subscribe(onNext: { (model) in
                print(model)
            }, onError: { (error) in
                self.errorMsg.accept(error.localizedDescription)
                self.isSuccess.accept(false)
            }, onCompleted: nil) {
                print("Disposed")
            }

the code works, but in the line //saveData(resMessageModel) I can't call it the function, I want to save the model, but if I try a call a function, Xcode show me this error: Unable to infer complex closure return type; add explicit type to disambiguate so, how can I resolve this?


Solution

  • Dale's answer works but I would be inclined to move the saves into do operators instead. Like this:

    networkManagerShareCore.share.login(param: param)
        .do(onNext: { [weak self] resMessageModel in
            self?.saveData(resMessageModel)
        })
        .flatMap { _ in
            networkManagerShareCore.share.me()
        }
        .do(onNext: { [weak self] resMeModel in
            self?.saveData(resMeModel)
        })
        .flatMap { resMeModel in
            networkManagerShareCore.share.entitie(entityId: "\(resMeModel.data.personId!)")
        }
        .subscribe(
            onNext: { (model) in
                print(model)
            },
            onError: { (error) in
                self.errorMsg.accept(error.localizedDescription)
                self.isSuccess.accept(false)
            },
            onCompleted: nil,
            onDisposed: {
                print("Disposed")
            }
        )
        .disposed(by: disposeBag)