您的位置:首页 > 理论基础 > 计算机网络

串行异步网络请求的简单实现

2016-05-06 13:33 666 查看
转载于:http://code4cocoa.com/2016/02/21/串行异步网络请求的简单实现/

最近在项目中遇到这样一个场景 —— 客户端数据需要一条一条的上传给服务器,且上一条上传成功,才开始上传下一条,如果上一条上传失败,则整个上传终止。实质上这就是一个串行异步网络请求的过程(串行执行一个异步任务序列)。

方案一

使用递归实现,网络请求部分我这里使用AFNetworking,当然也可以用其他的库。

 //仅列出关键代码
 
//仅列出关键代码

@property (strong, nonatomic) NSArarry *datasArray;

- (void)beginUploadData {
[self uploadDataToServer:self.datasArray[0] index:0];
}

- (void)uploadDataToServer:(id)data index:(NSUInteger)index {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager POST:@"url"
parameters:@{@"data":data}
success:^(AFHTTPRequestOperation *operation, id responseObject) {
if(index == self.datasArray.count - 1) {
//最后一条数据上传成功
}
else {
//上传下一条数据
[self uploadDataToServer:self.datasArray[index + 1] index:index + 1];
}
}
failure:^(AFHTTPRequestOperation *operation,NSError *error)  {
//提示错误
];
}
view rawdemo.m hosted with ❤ by GitHub

方案二

使用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来进行,可以看做方案二的加强版。这里就不提供示例代码了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios开发 串行异步