Asynchrone Operation mit ReactiveCocoa wiederholen

Ich verwende ReactiveCocoa-Signale, um Aufrufe an das RESTful-Backend in unserem System darzustellen. Jeder RESTful-Aufruf sollte ein Token als einen der Parameter erhalten. Das Token selbst wird vom Authentifizierungs-API-Aufruf empfangen.

Alles funktioniert einwandfrei, und wir haben jetzt das Ablaufen von Token eingeführt. Wenn der API-Aufruf mit HTTP-Code 403 fehlschlägt, muss sich die Back-End-Zugriffsklasse möglicherweise selbst neu autorisieren. Ich möchte diesen Vorgang für die Aufrufer vollständig transparent machen up with:

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

Ist das der richtige Weg?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage