【发布时间】:2014-01-20 19:32:52
【问题描述】:
我正在使用 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;
}
这是正确的做法吗?
【问题讨论】:
标签: ios frp reactive-cocoa