Повторная попытка асинхронной операции с использованием ReactiveCocoa

используя сигналы ReactiveCocoa для представления обращений к бэкенду RESTful в нашей системе. Каждый вызов RESTful должен получить маркер в качестве одного из параметров. Сам токен получен от вызова API аутентификации.

Все отлично работает и мыВ настоящее время введено истечение срока действия токена, поэтому классу внутреннего доступа может потребоваться повторная авторизация, если вызов API завершится неудачно с HTTP-кодом 403. Я хочу сделать эту операцию полностью прозрачной для вызывающих, это лучшее, что я придумал:

- (RACSignal *)apiCallWithSession:(Session *)session base:(NSString *)base params:(NSDictionary *)params get:(BOOL)get {
    NSMutableDictionary* p = [params mutableCopy];
    p[@"token"] = session.token;

    RACSubject *subject = [RACReplaySubject subject];

    RACSignal *first = [self apiCall:base params:p get:get];  // this returns the signal representing the asynchronous HTTP operation

    @weakify(self);
    [first subscribeNext:^(id x) {
        [subject sendNext:x];   // if it works, all is fine
    } error:^(NSError *error) {
        @strongify(self);

        // if it doesn't work, try re-requesting a token
        RACSignal *f = [[self action:@"logon" email:session.user.email password:session.user.password]
                         flattenMap:^RACStream *(NSDictionary *json) {  // and map it to the other instance of the original signal to proceed with new token
            NSString *token = json[@"token"];

            p[@"token"] = token;
            session.token = token;

            return [self apiCall:base params:p get:get];
        }];

        // all signal updates are forwarded, we're only re-requesting token once            
        [f subscribeNext:^(id x) {
            [subject sendNext:x];
        } error:^(NSError *error) {
            [subject sendError:error];
        } completed:^{
            [subject sendCompleted];
        }];
    } completed:^{
        [subject sendCompleted];
    }];

    return subject;
}

Это правильный способ сделать это?

Ответы на вопрос(1)

Ваш ответ на вопрос