我刚刚开始关注Reactive Cocoa,并认为我目前使用的许多应用程序中的场景应该是一个很好的起点。当应用程序启动时,它会在让用户进入应用程序之前检查用户当前是否位于白名单国家/地区。所以完美的顺序应该是这样的:
如果(1)失败,我想告知用户必须使用带有单个重试按钮的UIAlertView
启用位置服务。而这正是我无法理解这应该如何完成的地方。目前的代码如下:
@weakify( self )
[[[[[[self
findLocation]
doError:^( NSError *error ) {
@strongify( self )
// There was an error fetching the location so we ask
// the user to enable location services.
//
[self askUserToEnableLocationServices];
}]
retry] // What do we really retry here? It doesn't seem like it's [self findLocation]
flattenMap:^RACStream *( CLLocation *newLocation ) {
@strongify( self )
return [self reverseGeocodeLocation:newLocation];
}]
flattenMap:^RACStream *( NSString *ISOCountryCode ) {
@strongify( self )
return [self checkCountryPermissibleSignal:ISOCountryCode];
}]
subscribeNext:^( id x ) {
NSLog( @"Country is valid!" );
} error:^( NSError *error ) {
NSLog( @"Error: %@", error );
}];
有人对此有任何意见吗?我猜我错了retry
的工作方式。我也怀疑我对整个流程看起来有点天真。但是我现在已经坚持了几个晚上。还有一些尚未点击的东西。
答案 0 :(得分:4)
刚刚注意到你问过这个问题。 I posted a reply on the GitHub repo,但对于后代,我也会在这里发布我的答案:
@weakify( self )
[[[[[[self
findLocation]
doError:^( NSError *error ) {
@strongify( self )
// There was an error fetching the location so we ask
// the user to enable location services.
//
[self askUserToEnableLocationServices];
}]
retry] // What do we really retry here? It doesn't seem like it's [self findLocation]
-retry
不会再次致电[self findLocation]
。相反,它会创建对从[self findLocation]
返回的RACSignal对象的新订阅。由于在发送错误时信号如何操作的合同/语义传递了错误,因此原始订阅被处理掉。
请注意,您对-doError:
的调用中的代码将与新订阅同时执行,这可能不是您想要的。换句话说,当您向用户显示警报视图时,您同时会在用户有机会采取任何操作之前重新订阅从-findLocation
返回的信号。
如果在原始信号上发送错误,您可以使用-catchTo:
指定应订阅的替代信号:
@weakify( self )
RACSignal *recover = [RACSignal createSignal:^(id<RACSubscriber> subscriber) {
@strongify( self );
[self askTheUserToEnableLocationServices]
return nil;
}];
[[[[[self
findLocation]
catchTo:recover]
flattenMap:^RACStream *( CLLocation *newLocation ) {
@strongify( self )
return [self reverseGeocodeLocation:newLocation];
}]
flattenMap:^RACStream *( NSString *ISOCountryCode ) {
@strongify( self )
return [self checkCountryPermissibleSignal:ISOCountryCode];
}]
subscribeNext:^( id x ) {
NSLog( @"Country is valid!" );
} error:^( NSError *error ) {
NSLog( @"Error: %@", error );
}];