转载于:http://code4cocoa.com/2016/02/21/串行异步网络请求的简单实现/
最近在项目中遇到这样一个场景 —— 客户端数据需要一条一条的上传给服务器,且上一条上传成功,才开始上传下一条,如果上一条上传失败,则整个上传终止。实质上这就是一个串行异步网络请求的过程(串行执行一个异步任务序列)。
方案一
使用递归实现,网络请求部分我这里使用AFNetworking,当然也可以用其他的库。
//仅列出关键代码 | |
|
方案二
使用NSOperationQueue,网络请求部分使用NSURLSession,自然也可以使用AFNetworking。
//用了表示是否有异步请求正在执行
@property (assign, atomic) BOOL excuting;
@property (strong, nonatomic) NSArray *datasArray;
@property (strong, nonatomic) NSOperationQueue *operationQueue;
- (void)ViewDidLoad {
[super viewDidLoad];
self.excuting = NO;
self.operationQueue = [[NSOperationQueue alloc] init];
[self.operationQueue setMaxConcurrentOperationCount:1];
NSInvocationOperation *previousOperation = nil;
for(id data in datasArray) {
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(uploadDataToServer:)
object:data];
if(previousOperation) {
[operation addDependency:previousOperation]
}
[self.operationQueue addOperation:operation];
previousOperation = operation;
}
}
- (void)uploadDataToServer:(id)data {
NSURL *url = [NSURL URLWithString:@"https://api/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setTimeoutInterval:60];
[request setHTTPBody:data];
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession]
dataTaskWithRequest:request
completionHandler:^(NSData * _Nullable data,
NSURLResponse * _Nullable response,
NSError * _Nullable error) {
if (error) {
//该任务执行有错误,取消后续任务
[self.operationQueue cancelAllOperations];
}
else {
self.excuting = false;
}
}];
//如果有其他任务正在执行,则阻塞当前任务
while(self.excuting) {
}
//开始当前任务
[dataTask resume];
self.excuting = YES;
}
方案三
使用AFNetworking中,AFURLConnectionOperation的方法
- (NSArray )batchOfRequestOperations:(NSArray )operations
progressBlock:(void ( ^ )(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock
completionBlock:(void ( ^ )(NSArray * operations))completionBlock
配合NSOperationQueue来进行,可以看做方案二的加强版。这里就不提供示例代码了。