与原来是用嵌套的方式 不太好
图片和请求都可以用 利用出组和入组来限制回调顺序
图片
-(void)uploadImage1{
// 需要上传的数据
NSArray* images = [self images];
// 准备保存结果的数组,元素个数与上传的图片个数相同,先用 NSNull 占位
NSMutableArray* result = [NSMutableArray array];
for (UIImage* image in images) {
NSLog(@"image:%@",image);
[result addObject:[NSNull null]];
}
dispatch_group_t group = dispatch_group_create();
for (NSInteger i = 0; i < images.count; i++) {
//进入组
dispatch_group_enter(group);
NSURLSessionUploadTask* uploadTask = [self uploadTaskWithImage:images[i] completion:^(NSURLResponse *response, NSDictionary* responseObject, NSError *error) {
if (error) {
NSLog(@"第 %d 张图片上传失败: %@", (int)i + 1, error);
//出组
dispatch_group_leave(group);
} else {
NSLog(@"第 %d 张图片上传成功: %@", (int)i + 1, responseObject);
@synchronized (result) { // NSMutableArray 是线程不安全的,所以加个同步锁
result[i] = responseObject;
}
//出组
dispatch_group_leave(group);
}
}];
[uploadTask resume];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"上传完成!");
for (id response in result) {
NSLog(@"%@", response);
}
});
}
- (NSURLSessionUploadTask*)uploadTaskWithImage:(UIImage*)image completion:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionBlock {
// 构造 NSURLRequest
NSError* error = NULL;
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[self uploadUrl] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
NSData* imageData = UIImageJPEGRepresentation(image, 1.0);
[formData appendPartWithFileData:imageData name:@"file" fileName:@"someFileName" mimeType:@"multipart/form-data"];
} error:&error];
// 可在此处配置验证信息
// 将 NSURLRequest 与 completionBlock 包装为 NSURLSessionUploadTask
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:^(NSProgress * _Nonnull uploadProgress) {
} completionHandler:completionBlock];
return uploadTask;
}
数据
-(void)test2{
NSMutableArray *arrPostUrl = [[NSMutableArray alloc] init];
[arrPostUrl addObject:@"1"];
[arrPostUrl addObject:@"2"];
NSMutableArray *arrDict = [[NSMutableArray alloc] init];
[arrDict addObject:@{@"Id":@""}];
[arrDict addObject:@{@"mobile":@""}];
// 准备保存结果的数组 先用 NSNull 占位
NSMutableArray* result = [NSMutableArray array];
for (int i=0;i<arrPostUrl.count;i++) {
[result addObject:[NSNull null]];
}
dispatch_group_t group = dispatch_group_create();
for (NSInteger i = 0; i < arrPostUrl.count; i++) {
//进入组
dispatch_group_enter(group);
NSURLSessionDataTask *uploadTask = [self postUrl:arrPostUrl[i] params:arrDict[i] showHUD:YES successBlock:^(id returnData, int code, NSString *msg) {
@synchronized (result) { // NSMutableArray 是线程不安全的,所以加个同步锁
result[i] = returnData;
}
//出组
dispatch_group_leave(group);
} failureBlock:^(NSError *error) {
//出组
dispatch_group_leave(group);
}];
[uploadTask resume];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"完成!");
for (id response in result) {
NSLog(@"%@", response);
}
});
}
-(NSURLSessionDataTask *)postUrl:(NSString *)url
params:(NSDictionary *)params
showHUD:(BOOL)showHUD
successBlock:(MHAsiSuccessBlock)successBlock
failureBlock:(MHAsiFailureBlock)failureBlock{
//地址
NSString *postUrl = url;
//参数
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
//设置基础请求地址
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json",@"text/javascript", nil];
if (showHUD==YES) {
//[MBProgressHUD showHUDAddedTo:nil animated:YES];
}
return [manager POST:postUrl parameters:dic progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//[MBProgressHUD hideHUDForView:nil animated:YES];
int code = 0;
NSString *msg = nil;
id dictFromNet = responseObject;
NSLog(@"--请求参数--:%@",params);
if (dictFromNet) {
NSString *success = dictFromNet[@"success"];
code = success.intValue;
// if (NotNilAndNull(dictFromNet[@"message"])) {
msg = dictFromNet[@"message"];
// }else{
// msg = FAILNETREQUEST;
// }
}
NSLog(@"\n\n----请求的返回结果 %@\n",dictFromNet);
if (successBlock) {
successBlock(dictFromNet,code,msg);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//[MBProgressHUD hideHUDForView:nil animated:YES];
NSLog(@"---error==%@\n%@\n",error,error.localizedDescription);
if (failureBlock) {
failureBlock(error);
}
}];
}
第二种是队列感觉没有第一种简单
-(void)uploadImage2{
// 需要上传的数据
NSArray* images = [self images];
// 准备保存结果的数组,元素个数与上传的图片个数相同,先用 NSNull 占位
NSMutableArray* result = [NSMutableArray array];
for (UIImage* image in images) {
[result addObject:[NSNull null]];
}
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 5;
NSBlockOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ // 回到主线程执行,方便更新 UI 等
NSLog(@"上传完成!");
for (id response in result) {
NSLog(@"%@", response);
}
}];
}];
for (NSInteger i = 0; i < images.count; i++) {
NSURLSessionUploadTask* uploadTask = [self uploadTaskWithImage:images[i] completion:^(NSURLResponse *response, NSDictionary* responseObject, NSError *error) {
if (error) {
NSLog(@"第 %d 张图片上传失败: %@", (int)i + 1, error);
} else {
NSLog(@"第 %d 张图片上传成功: %@", (int)i + 1, responseObject);
@synchronized (result) { // NSMutableArray 是线程不安全的,所以加个同步锁
result[i] = responseObject;
}
}
}];
HAMURLSessionWrapperOperation *uploadOperation = [HAMURLSessionWrapperOperation operationWithURLSessionTask:uploadTask];
[completionOperation addDependency:uploadOperation];
[queue addOperation:uploadOperation];
}
[queue addOperation:completionOperation];
}
Demo http://download.csdn.net/detail/rpf2014/9760995