多张图片上传服务器

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

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

三.保留数据的做法.

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

今天就写到这了.周六早晨就下雨,感觉挺舒服清爽的!

补丁:Demo 地址 2016/8/17

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容