iOS-图片批量上传-挖坑

背景

注:这个方法有坑。。【戳--填坑版】
最近一个半路接手的项目需要修改一个功能。图片上传。项目中有很多地方用到了图片上传这个功能,有的是单张的,有的是批量上传的。现在需要全部改为批量上传。还有新增图片上传的状态:未上传、上传中、上传失败、上传成功。上传失败需要有一个点击重传的功能。

没有将代码抽离出来,就不放代码了。涉及具体业务的部分为了保密性也不放了。。主要就是介绍一下思想,捋一下思路

iOS-图片批量上传-挖坑_第1张图片
E003ADF08B70DAB3CB345398206A7403.jpg

动手1

因为对别人写的代码不太熟悉,粗略的看过一遍后,决定先改好改的部分。然后在熟悉的过程中看看别人的思路以及牵扯到的需要修改的地方。从结果往前推。首先给图片部分加上显示的状态。找到图片显示控件,新增控件需要的状态。

//上传中的半透明遮罩
@property (nonatomic, strong) UIImageView *maskView;
//点击重传的按钮
@property (nonatomic, strong) UILabel *reUpload;
//上传中的转动图片
@property (nonatomic, strong) UIImageView *uploading;

加号之后我们需要一个变量对这些控件进行显示与隐藏。所以我们要知道这些状态。再来看看现有的这个类中提供了哪些外部更新的方法。

- (void)setImage:(UIImage *)image;

- (void)setImageUrl:(NSString *)imgUrl;

- (void)clearImage;

其中 imgUrl是上传成功后接口返回的图片地址,当上传成功后接口会按上传顺序返回图片的一串URL,失败的那张图片会返回空信息。拿到结果后我们会调用这个方法去刷新。这个时候我们可以拿到 【成功】和【失败】 的状态。拿另外两个【未上传】以及【上传中】就可以通过

- (void)setImage:(UIImage *)image

这个方法来判断。image==nil 未上传

动手2

接下来是图片来源的问题。
上传的图片通过

  • 拍照
  • 相册多张选择
  • 相册单张选择(【上传失败】需要重传照片)

主要是修改相册作为图片源的部分。让点击添加的时候为多张,重传的时候为一张。批量上传使用了别人开源的控件ZYQAssetPickerController,使用懒加载的方式初始化它。

if (_addImgIndex == _imageArray.count) {
    //这个部分是新加的,_addImgIndex指的是点击添加图片的index,_imageArray存储照片的数组,用于未上传时候的展示
    [self presentViewController:self.pickerController animated:YES completion:nil];
 } else {
     UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
     imagePicker.delegate = self;
     imagePicker.allowsEditing = NO;
     imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
     [self presentViewController:imagePicker animated:YES completion:nil];
 }

动手3

照片选择完成后的回调,包括图片的显示,图片的
上传。
原先是点一张上传一张,不存在未上传时候的显示问题。所以我们需要添加一些全局变量来存储一些东西。

@property (nonatomic, strong) NSMutableArray *imageArray;   //存储图片
@property (nonatomic, assign) NSInteger addImgIndex;  //添加照片的index;
@property (nonatomic, assign) NSInteger imageCount;  //与上一个结合起来

当前的controller实现ZYQAssetPickerControllerDelegate。开辟一个子线程拿到图片后,调用存储的方法,将图片存入内存。mutaFile用来存储图片文件用来上传。

- (void)assetPickerController:(ZYQAssetPickerController *)picker didFinishPickingAssets:(NSArray *)assets
{
    _isCamera = NO;
    _imageCount = assets.count + _imageArray.count;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSMutableArray *mutaFile = [NSMutableArray new];
        for (int i=0; i

当所有的图片存储完毕后我们切回主线程,刷行UI,显示图片。并将图片至于【上传中】的状态,调用上传文件的方法上传文件。

- (void)saveImage:(UIImage *)image fileArr:(NSMutableArray *)filePathArr
{
    
   //省略了图片的压缩,存储,以及文件的初始化
    if (!_imageArray) {
        _imageArray = [NSMutableArray array];
    }
    if (_addImgIndex == _imageArray.count) {
        [_imageArray addObject:image];
        [self.viewModel.showImgUrlArr addObject:@"**"];
        [self.viewModel.imgUrlArr addObject:@"**"];
    } else {
        [_imageArray replaceObjectAtIndex:_addImgIndex withObject:image];
        [self.viewModel.showImgUrlArr replaceObjectAtIndex:_addImgIndex withObject:@"**"];
        [self.viewModel.imgUrlArr replaceObjectAtIndex:_addImgIndex withObject:@"**"];
    }
    
    [filePathArr addObject:file];
    if (_isCamera) {
        _isCamera = NO;
        dispatch_async(dispatch_get_main_queue(),^{
            [self.tableView reloadData];
        });
        [self uploadImage:filePathArr];
    }
    else
    {
        
        if (_imageCount == _imageArray.count) {
            dispatch_async(dispatch_get_main_queue(),^{
                [self.tableView reloadData];
            });
            [self uploadImage:filePathArr];
        }
    }
    
}

其中showImgUrlArr和imgUrlArr都是接口返回的,用**代表上传中,##代表上传失败。在拿到上传结果后给他replaceObjectAtIndex。这样在用户点击下一步的时候,能弹框告诉用户图片的上传状态,拦截当前页面的保存操作。

思考时间做多的地方

当图片分次批量上传的时候,怎么处理这个URL对应的替换操作。接口并没有返回当前这个URL指向的图片的下标。后来我修改了上传的文件数组,原来这个图片文件数组是全局变量,保存了所有要显示的图片,包括已经上传成功后的图片。将它改为当前需要上传图片,作用域只在相册及相机回调 方法内,然后将文件命名为 0,1,2...


iOS-图片批量上传-挖坑_第2张图片
上传图片方法.png

刷新方法里面根据showImgUrl来判断展示什么状态。

AddImgView *addView = [[AddImgView alloc] init];
       if ([mulArr[i] isEqualToString:@"**"] || [mulArr[i] isEqualToString:@"##"]) {
           //上传中图片  + 上传失败
           [addView setImage:imageArr[i] reload:[mulArr[i] isEqualToString:@"##"]];
       } else if ([mulArr[i] isEqualToString:@""]) {
       
       } else {
           [addView setImageUrl:imgUrlArr[i]];
       }

总结

改别人的代码总觉得很难受,中间发生过很多意外的情况,没有自己写的顺手。因为不清楚之前的具体需求,会忽略掉某些边界以及特殊情况。只能自己一次次的debug。不过看别人的代码学习的一种吧。总不可能每个项目都是从0开始的。。但是涉及到很多文件的修改真的想吐血啊。

你可能感兴趣的:(iOS-图片批量上传-挖坑)