5

リクエストを行う前に、必要に応じてユーザーを再承認する Observable を使用して、Java アプリで認証された呼び出しをラップしようとしています。Shape Code Blogのこのアプローチを使用して、Objective-C の ReactiveCocoa で同様のことを行いました。

- (RACSignal *)doRequestAndRefreshTokenIfNecessary:(RACSignal *)requestSignal {
    return [requestSignal catch:^(NSError *error) {
        // Catch the error, refresh the token, and then do the request again.
        BOOL hasRefreshToken = [UserManager sharedInstance].refreshToken != nil;
        BOOL httpCode401AccessDenied = error.code == -1011;
        if (httpCode401AccessDenied && hasRefreshToken) {
            NSLog(@"Will attempt to refresh access token.");
            return [[[self refreshToken] ignoreValues] concat:requestSignal];
        }
        return requestSignal;
    }];
}

RACSignal は、Observable に類似した ReactiveCocoa です。このメソッドは、最初のリクエストによって通知されたエラーをキャッチする RACSignal を作成し、そのエラーが指定された基準に一致する場合 (この場合、アクセスが拒否され、利用可能な認証トークンがある場合)、新しい RACSignal が透過的に起動され、更新トークンが使用されます。元の信号を再送信します。

RxJava は同様の機能を提供しますか? Combining Observablesのドキュメントcatch:に似たものは見つかりませんでした。

4

1 に答える 1

2

RxJava 内に事前に存在するものはないように見えますが、これはうまくいくようです (ReactiveCocoa のキャッチからのかなり直接的な翻訳):

public class CatchObservable  {
    public interface CaughtErrorHandler {
        public Observable<?> onError(Throwable throwable);
    }

    public static <T> Observable catchObserver(final Observable<T> observable, final CaughtErrorHandler errorHandler) {
        return Observable.create(new Observable.OnSubscribeFunc<T>() {
            @Override
            public Subscription onSubscribe(final Observer<? super T> subscriber) {
                return observable.subscribe(new Observer<T>() {
                    @Override
                    public void onCompleted() {
                        subscriber.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Observable observable = errorHandler.onError(e);
                        observable.subscribe(subscriber);
                    }

                    @Override
                    public void onNext(T args) {
                        subscriber.onNext(args);
                    }
                });
            }
        });
    }
}

したがって、次のように使用されます。

private Observable refreshAuthIfNecessary(final Observable<?> request) {
    return CatchObservable.catchObserver(request, new CatchObservable.CaughtErrorHandler() {
        @Override
        public Observable<?> onError(Throwable throwable) {
            return Observable.concat(WebServices.this.refreshAuth(), request);
        }
    });
}
于 2014-03-16T04:06:16.227 に答える