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

转载于: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来进行,可以看做方案二的加强版。这里就不提供示例代码了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值