вызовите удовольствие c в асинхронных запросах, объединяющих RxSwift и Alamofire - PullRequest
1 голос
/ 29 января 2020

Я новичок в RxSwift, и это моя проблема, мое приложение должно выполнить 3 запроса, 3 из них gets, моя рабочая группа предлагает мне использовать flatmap для выполнения этого трех запросов подряд, но я не знаю, как мне использовать flatmap.

это мои запросы

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()
        }
    }

первая конечная точка - login с ее параметрами, затем me, функция me ответьте идентификатору, этот идентификатор необходим для третьего запроса, то есть entitie.

Я делаю плоскую карту следующим образом.

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")
            }

код работает, но в строке //saveData(resMessageModel) Я не могу назвать это функцией, я хочу сохранить модель, но если я попытаюсь вызвать функцию, Xcode покажет мне эту ошибку: Unable to infer complex closure return type; add explicit type to disambiguate так, как я могу решить эту проблему?

Ответы [ 2 ]

1 голос
/ 29 января 2020

RxSwift flatMap ожидает возвращаемое значение некоторого Observable.

Оператор FlatMap преобразует Observable, применяя указанную вами функцию к каждому элементу, излучаемому источником Observable, где эта функция возвращает Observable это само по себе испускает элементы.

Вы должны добавить оператор возврата в каждом вызове flatMap. Кроме того, вам нужно явно определить тип возвращаемого значения для замыканий.

Таким образом, внутренний внутренний вызов flatMap должен выглядеть примерно так:

 networkManagerShareCore.share.me()
       .flatMap { resMeModel -> Observable<entitieModel> in
             //saveData(resMessageModel)
             return networkManagerShareCore.share.entitie(entityId: "\(resModelMe.data.personId!)")

Обычно вы не вставляете flatMap в flatMap, но просто составьте их последовательно, чтобы сделать код более понятным. И не забывайте распоряжаться (мимо :). Конечный результат будет выглядеть примерно так:

networkManagerShareCore.share.login(param: param)
    .flatMap { resMessageModel -> Observable<meModel> in
          //saveData(resMessageModel)
          return networkManagerShareCore.share.me()
     }
     .flatMap { resMeModel -> Observable<entitieModel> in
           //saveData(resMessageModel)
           return 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")
     }
     .disposed(by: disposeBag)
0 голосов
/ 29 января 2020

Ответ Дейла работает, но я был бы склонен вместо этого переместить сейвы в операторы do. Как это:

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)
...