我使用 NSOperationQueue (正如欧文所建议的那样)。将 NSURLSessionTasks 放在 NSOperation 子类中并设置任何依赖项。依赖任务会等到它们所依赖的任务完成后再运行,但不会检查状态(成功或失败),因此添加一些逻辑来控制流程。
在我的例子中,第一个任务检查用户是否有一个有效的帐户,并在必要时创建一个。在第一个任务中,我更新了一个 NSUserDefault 值以指示该帐户有效(或存在错误)。第二个任务检查 NSUserDefault 值,如果一切正常,则使用用户凭据将一些数据发布到服务器。
(将 NSURLSessionTasks 粘贴在单独的 NSOperation 子类中也使我的代码更易于导航)
将 NSOperation 子类添加到 NSOperationQueue 并设置任何依赖项:
NSOperationQueue *ftfQueue = [NSOperationQueue new];
FTFCreateAccount *createFTFAccount = [[FTFCreateAccount alloc]init];
[createFTFAccount setUserid:@"********"]; // Userid to be checked / created
[ftfQueue addOperation:createFTFAccount];
FTFPostRoute *postFTFRoute = [[FTFPostRoute alloc]init];
[postFTFRoute addDependency:createFTFAccount];
[ftfQueue addOperation:postFTFRoute];
在第一个 NSOperation 子类中,检查服务器上是否存在帐户:
@implementation FTFCreateAccount
{
NSString *_accountCreationStatus;
}
- (void)main {
NSDate *startDate = [[NSDate alloc] init];
float timeElapsed;
NSString *ftfAccountStatusKey = @"ftfAccountStatus";
NSString *ftfAccountStatus = (NSString *)[[NSUserDefaults standardUserDefaults] objectForKey:ftfAccountStatusKey];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setValue:@"CHECKING" forKey:ftfAccountStatusKey];
// Setup and Run the NSURLSessionTask
[self createFTFAccount:[self userid]];
// Hold it here until the SessionTask completion handler updates the _accountCreationStatus
// Or the process takes too long (possible connection error)
while ((!_accountCreationStatus) && (timeElapsed < 5.0)) {
NSDate *currentDate = [[NSDate alloc] init];
timeElapsed = [currentDate timeIntervalSinceDate:startDate];
}
if ([_accountCreationStatus isEqualToString:@"CONNECTION PROBLEM"] || !_accountCreationStatus) [self cancel];
if ([self isCancelled]) {
NSLog(@"DEBUG FTFCreateAccount Cancelled" );
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setValue:@"ERROR" forKey:ftfAccountStatusKey];
}
}
在下一个 NSOperation 发布数据中:
@implementation FTFPostRoute
{
NSString *_routePostStatus;
}
- (void)main {
NSDate *startDate = [[NSDate alloc] init];
float timeElapsed;
NSString *ftfAccountStatusKey = @"ftfAccountStatus";
NSString *ftfAccountStatus = (NSString *)[[NSUserDefaults standardUserDefaults] objectForKey:ftfAccountStatusKey];
if ([ftfAccountStatus isEqualToString:@"ERROR"])
{
// There was a ERROR in creating / accessing the user account. Cancel the post
[self cancel];
} else
{
// Call method to setup and run json post
// Hold it here until a reply comes back from the operation
while ((!_routePostStatus) && (timeElapsed < 3)) {
NSDate *currentDate = [[NSDate alloc] init];
timeElapsed = [currentDate timeIntervalSinceDate:startDate];
NSLog(@"FTFPostRoute time elapsed: %f", timeElapsed);
}
}
if ([self isCancelled]) {
NSLog(@"FTFPostRoute operation cancelled");
}
}