多张图片上传服务器

来源:互联网 发布:网络赢钱游戏 编辑:程序博客网 时间:2024/04/20 01:12

       最近遇到问题就是多张图片上传服务器该怎么设置.刚开始想到的第一想法就是创建个串行队列.吧这个串行队列放在子线程.循环去上传.首先,在这里.我们首先模拟一个网络请求的方法.

#pragma mark -模拟网络请求-

- (void)GET:(NSString*)url

parameter:(NSDictionary*)parmeter

success:(void(^)(idrespondObject))success

failure:(void(^)(NSError*error))failure{

NSError*error;

if([parmeter[@"id"]isEqualToString:@"0"]) {

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

failure(error);

});

}else{

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

success(@"");

});

}

}

一.下来就来写第一种想到的串行队列的想法

1.定个全局标示.来记录上传的个数

@property(nonatomic,assign)NSUIntegerindex;

2.分发任务,请求

//创建一个串行队列

dispatch_queue_tqueue =dispatch_queue_create("com.xxx.www",NULL);

//分发任务,放到子线程中

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

dispatch_apply(_images.count, queue, ^(size_tindex) {

[selfGET:@"url"parameter:@{@"youparmater":@"imageStr",@"id": [NSStringstringWithFormat:@"%u",arc4random() %2]}success:^(idrespondObject) {

//记录

_index++;

}failure:^(NSError*error) {

_index++;

}];

});

});

这样写有很大的局限性,不能准确的记录是哪张上传失败,还有想要一张完了再下一张,就像 qq 发说说有图片那样的进度提示,就不好做了.

接下来就说说我们的第二种方法,第二方法用到递归算法,主要的思想就是:递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回.这里感谢我的好友顾梦晓,当时是和他讨论这个问题时,才想出的这个解决方法.

二.递归算法

1.创建几个全局标识

//图片数据源

@property(nonatomic,strong)NSMutableArray*images;

//标示的下标

@property(nonatomic,assign)NSUIntegerindex;

//第一种失败回调所需存储失败数据

@property(nonatomic,strong)NSMutableArray*faileIndexs;

2.测试调用的函数

- (void)test{

_images= [@[[UIImageimageNamed:@"scenery1.jpg"], [UIImageimageNamed:@"scenery2.jpg"], [UIImageimageNamed:@"scenery3.jpg"], [UIImageimageNamed:@"scenery4.jpg"]]mutableCopy];

_faileIndexs= [NSMutableArrayarray];

//上传图片

[selfupdateImage:_images[0]completion:^(NSUIntegerindex,BOOLisSuccess) {

//1.失败回调1的情况处理

if(isSuccess) {

if(index ==_images.count) {

NSLog(@"上传完毕,失败的张数为:%@",_faileIndexs);

}

NSLog(@"上传过程第%lu张成功",index);

}else{

if(index ==_images.count) {

NSLog(@"上传完毕,失败的张数为:%@",_faileIndexs);

}

[_faileIndexsaddObject:@(index)];

NSLog(@"上传过程第%lu张失败",index);

}

//2.失败回调2的情况处理

/*

if (isSuccess) {

if (index == _images.count) {

//上传所有图片的成功

NSLog(@"上传所有的成功");

}

NSLog(@"上传过程第%lu张成功",index);

}else{

//上传图片失败

NSLog(@"上传图片失败,止于第%lu张",index);

}

*/

}];

}

3.上传图片的递归算法函数

- (void)updateImage:(UIImage*)image completion:(void(^)(NSUIntegerindex,BOOLisSuccess))completion{

//压缩图片,看自己的要求压缩比例设置compressionQuality参数,此参数最好在2-7之间.太小泽压缩容易失真,太大占用内存太大

NSData*dataImage =UIImageJPEGRepresentation(image,1);

//转换的参数有四个枚举,分别为:

// NSDataBase64Encoding64CharacterLineLength = 1UL << 0,将最大行长度设置为64个字符,插入你所指定的那一行

// NSDataBase64Encoding76CharacterLineLength = 1UL << 1,将最大行长度设置为76个字符,插入你所指定的那一行

//以下可以控制结束行数的:

// NSDataBase64EncodingEndLineWithCarriageReturn = 1UL << 4,设置最大行长度64个字符,并可以指定在哪行结束

// NSDataBase64EncodingEndLineWithLineFeed = 1UL << 5,指定最大行长度76个字符,并指定在哪行结束

//这个转换可以自行google base64加密

NSString*imageStr = [dataImagebase64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

[selfGET:@"url"parameter:@{@"youparmater": imageStr,@"id": [NSStringstringWithFormat:@"%u",arc4random() %2]}success:^(idrespondObject) {

//如果上传成功

_index++;

//回调

completion(_index,YES);

if(_index==_images.count) {

//全部上传成功

//清空标示

_index=0;

return;

}

//继续下一行张

[selfupdateImage:_images[_index]completion:completion];

}failure:^(NSError*error) {

//先判断是否是最后一张,如果是,则返回

if(_index==_images.count-1) {

completion(_index+1,NO);

//清空标示

_index=0;

return;

}

//失败,分两种情况:

//1.跳过失败的那张,返回失败信息,继续下张上传

_index++;

completion(_index,NO);

[selfupdateImage:_images[_index]completion:completion];

//2.直接返回,不在进行接下来的上传工作

/*

completion(_index + 1, NO);

//清空标示

_index = 0;

return ;

*/

}];

}

备注:

1.这里列举了两种处理方法:第一种是:只要是失败了就直接停止在那张就可以了,提示用户继续或者取消,这是根据回调的标识下标就可以处理数据源来重试或者取消.第二种方法就是:一张失败后,回调记录,接着下张继续上传.在全部操作完成后再提示用户失败的图片.

2.在上传图片的递归函数中,在递归调用 block 的时候切记要将第一次传进来的 blcok 递归传递给后一个函数,不然下个函数的 block 就会被替代.成功或者失败的回调在图片张数大于1时,永远不会被回调了.

3.如果要自己修改需求.一定要写好边界条件.递归在适当的时候返回,不然就会成死循环了.

4.全局的下标标识,在完成后一定要清零,不然在同个界面再次操作的时候,标示还保留的上次的最大值,再次调用函数,会抛出异常.数组越界.

三.保留数据的做法.

     这点笔者并没有写,就谈谈思路,就是保留数据.当用户点击了保存后,应该把数据保存到数据库,在上传服务器,这时候就不会让提示失败,我们会始终把数据上传到服务器为止.我看在处理蓝牙接受到的数据就是这样处理的,应为该数据为不保留性,过了就会没有了,但是用户要用这块数据,不能丢失用户的数据,所以我们应该将此数据保留到数据库,上传服务器成功为止.用户多张图片感觉也是这样,应为这几张图片是用户在自己的相册精挑细选出来的,用户想的就是要这图片.不应该就因为一些原因丢失用户的数据.哟感兴趣的小伙伴可以试试.


原创粉丝点击