2

我遇到了以下错误:

Cannot convert value of type '(_) -> Observable<Response>' 
to expected argument type '([_]) -> _'

当我尝试编译时:

func request(_ token: MyAPI) -> Observable<Moya.Response> {
    switch (target.requiresCSRF, target.requiresOAuth) {
    case (false, false): return actualRequest 
    case (true, false): return CSRFTokenRequest().flatMap { _ in actualRequest }
    case (false, true): return OAuthTokenRequest().flatMap { _ in actualRequest }
    case (true, true): return Observable.zip([CSRFTokenRequest(), OAuthTokenRequest()]) { _ in actualRequest }
    } 
}

actualRequest 的类型Observable<Response> 为 CSRFTokenRequest 和 OAuthTokenRequest 的类型均为Observable<String?>

我试图在OAuthTokenRequest之前运行CSRFTokenRequest,然后是实际请求。

以下解决了这个问题......但我不确定这是否是正确的方法......

return RequiresCSRFTokenRequest().flatMap{ _ in
            self.RequiresAuthenticationRequest().flatMap{ _ in actualRequest}
        }



fileprivate extension Networking{

    func RequiresAuthenticationRequest() -> Observable<String> {

        /// This has 3 cases

        // 0. token is not present, error out
        // 1. token is not expired, return token
        // 2. token is expired, needs refresh

        guard let jwt = AuthManager.shared.accessToken else{
            return .just("Error!! No access tokens")
        }

        // If access token is valid
        if AuthManager.shared.expiredAccessToken == false{

            return .just(jwt)

        }else{

            return request(.refreshAccessToken(refreshToken: AuthManager.shared.refreshTokenWithBearer!))
                .filterSuccessfulStatusCodes()
                .mapObject(type: UserAuthenticationTokens.self)
                .do(onNext: {
                    $0.save()})
                .map{ (token) -> String in
                    // Get new access token that was just saved
                    return AuthManager.shared.accessToken!
            }
        }

    }


    func RequiresCSRFTokenRequest() -> Observable<String> {

        // Always get a new csrf token
        return request(.getCSRF())
            .filterSuccessfulStatusCodes()
            .mapObject(type: CSRFToken.self)
            .do(onNext: {
                $0.save()
            }).map{ (token) -> String in
                return AuthManager.shared.csrf_token!
            }
    }

}

谢谢!

4

1 回答 1

1

据我所知,如果您仔细查看语句中的最后一个案例,以及两个函数和正在返回switch的事实,您正在创建一个等待两者发出的新函数。CSRFTokenRequest()OAuthTokenRequest()Observables<String?>Observable

zip为您发出两个 Observables,在您的情况下,您使用 { _ return actualRequest } 省略两者。但是当你返回actualRequest它期望另一件事的函数时要小心,所以这里的重点是将 an 转换Observable<A>为 an Observable<B>

为此,您将需要flatMap像以前一样使用该功能,而在最后一种情况下您错过了它。

因此,让我们看一下示例:

Observable.zip(Observable.just(1), Observable.just("!")) { (a, b) in
   return (a,b)
}
.flatMap {  _ in return Observable.just(4.0) }
.subscribe(onNext: { value in
    print(value)
})
.addDisposableTo(disposeBag)

在上面的例子中,我省略了Observable<Int>and的两个值Observable<String>来创建一个新的Observable<Double>

在您的情况下,您应该执行以下操作:

return Observable.zip(CSRFTokenRequest(), OAuthTokenRequest()).flatMap { _ in actualRequest }

我希望这对你有帮助

于 2016-12-03T02:50:08.997 回答