面试:ios 批量上传图片
这几天面试,被问到关于GCD的用法,想了想,之前项目好像确实用的比较少,只是知道怎么用,有思路,但是却从来没有试过,回来之后,就尝试写了下:
封装图片上传的方法
/**批量上传图片*/ + (NSURLSessionUploadTask*)uploadTaskWithImage:(UIImage*)image completion:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionBlock { // 构造 NSURLRequest NSError* error = NULL; NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[NSString stringWithFormat:@"%@%@",JHTestUrl,JHPostImageFileURL] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { NSData* imageData = UIImageJPEGRepresentation(image, 1.0); [formData appendPartWithFileData:imageData name:@"file1" fileName:@"someFileName.png" mimeType:@"image/png"]; } 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; }
GCD方法监听每张图片的上传进度
/** * 批量上传图片的处理方法(GCD) * * @param images 要上传的图片数组 * @param completion 上传完成之后的正确返回路径 */ +(void)uploadImagesWithImages:(NSArray <UIImage *>*)images completion:(void(^)(NSMutableArray *successResultPath))completion{ // 准备保存结果的数组,元素个数与上传的图片个数相同,先用 NSNull 占位 NSMutableArray* result = [NSMutableArray array]; for (NSInteger i = 0; i<images.count; i++) { [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(), ^{ if (completion) { completion(result); } }); }