Повторная попытка асинхронной операции с использованием 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;
}
Это правильный способ сделать это?