多張圖片上傳服務(wù)器

? ? ? ?最近遇到問題就是多張圖片上傳服務(wù)器該怎么設(shè)置.剛開始想到的第一想法就是創(chuàng)建個串行隊列.吧這個串行隊列放在子線程.循環(huán)去上傳.首先,在這里.我們首先模擬一個網(wǎng)絡(luò)請求的方法.

#pragma mark -模擬網(wǎng)絡(luò)請求-

- (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.定個全局標(biāo)示.來記錄上傳的個數(shù)

@property(nonatomic,assign)NSUIntegerindex;

2.分發(fā)任務(wù),請求

//創(chuàng)建一個串行隊列

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

//分發(fā)任務(wù),放到子線程中

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++;

}];

});

});

這樣寫有很大的局限性,不能準(zhǔn)確的記錄是哪張上傳失敗,還有想要一張完了再下一張,就像 qq 發(fā)說說有圖片那樣的進(jìn)度提示,就不好做了.

接下來就說說我們的第二種方法,第二方法用到遞歸算法,主要的思想就是:遞歸需要有邊界條件、遞歸前進(jìn)段和遞歸返回段。當(dāng)邊界條件不滿足時,遞歸前進(jìn);當(dāng)邊界條件滿足時,遞歸返回.這里感謝我的好友顧夢曉,當(dāng)時是和他討論這個問題時,才想出的這個解決方法.

二.遞歸算法

1.創(chuàng)建幾個全局標(biāo)識

//圖片數(shù)據(jù)源

@property(nonatomic,strong)NSMutableArray*images;

//標(biāo)示的下標(biāo)

@property(nonatomic,assign)NSUIntegerindex;

//第一種失敗回調(diào)所需存儲失敗數(shù)據(jù)

@property(nonatomic,strong)NSMutableArray*faileIndexs;

2.測試調(diào)用的函數(shù)

- (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.失敗回調(diào)1的情況處理

if(isSuccess) {

if(index ==_images.count) {

NSLog(@"上傳完畢,失敗的張數(shù)為:%@",_faileIndexs);

}

NSLog(@"上傳過程第%lu張成功",index);

}else{

if(index ==_images.count) {

NSLog(@"上傳完畢,失敗的張數(shù)為:%@",_faileIndexs);

}

[_faileIndexsaddObject:@(index)];

NSLog(@"上傳過程第%lu張失敗",index);

}

//2.失敗回調(diào)2的情況處理

/*

if (isSuccess) {

if (index == _images.count) {

//上傳所有圖片的成功

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

}

NSLog(@"上傳過程第%lu張成功",index);

}else{

//上傳圖片失敗

NSLog(@"上傳圖片失敗,止于第%lu張",index);

}

*/

}];

}

3.上傳圖片的遞歸算法函數(shù)

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

//壓縮圖片,看自己的要求壓縮比例設(shè)置compressionQuality參數(shù),此參數(shù)最好在2-7之間.太小澤壓縮容易失真,太大占用內(nèi)存太大

NSData*dataImage =UIImageJPEGRepresentation(image,1);

//轉(zhuǎn)換的參數(shù)有四個枚舉,分別為:

// NSDataBase64Encoding64CharacterLineLength = 1UL << 0,將最大行長度設(shè)置為64個字符,插入你所指定的那一行

// NSDataBase64Encoding76CharacterLineLength = 1UL << 1,將最大行長度設(shè)置為76個字符,插入你所指定的那一行

//以下可以控制結(jié)束行數(shù)的:

// NSDataBase64EncodingEndLineWithCarriageReturn = 1UL << 4,設(shè)置最大行長度64個字符,并可以指定在哪行結(jié)束

// NSDataBase64EncodingEndLineWithLineFeed = 1UL << 5,指定最大行長度76個字符,并指定在哪行結(jié)束

//這個轉(zhuǎn)換可以自行g(shù)oogle base64加密

NSString*imageStr = [dataImagebase64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

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

//如果上傳成功

_index++;

//回調(diào)

completion(_index,YES);

if(_index==_images.count) {

//全部上傳成功

//清空標(biāo)示

_index=0;

return;

}

//繼續(xù)下一行張

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

}failure:^(NSError*error) {

//先判斷是否是最后一張,如果是,則返回

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

completion(_index+1,NO);

//清空標(biāo)示

_index=0;

return;

}

//失敗,分兩種情況:

//1.跳過失敗的那張,返回失敗信息,繼續(xù)下張上傳

_index++;

completion(_index,NO);

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

//2.直接返回,不在進(jìn)行接下來的上傳工作

/*

completion(_index + 1, NO);

//清空標(biāo)示

_index = 0;

return ;

*/

}];

}

備注:

1.這里列舉了兩種處理方法:第一種是:只要是失敗了就直接停止在那張就可以了,提示用戶繼續(xù)或者取消,這是根據(jù)回調(diào)的標(biāo)識下標(biāo)就可以處理數(shù)據(jù)源來重試或者取消.第二種方法就是:一張失敗后,回調(diào)記錄,接著下張繼續(xù)上傳.在全部操作完成后再提示用戶失敗的圖片.

2.在上傳圖片的遞歸函數(shù)中,在遞歸調(diào)用 block 的時候切記要將第一次傳進(jìn)來的 blcok 遞歸傳遞給后一個函數(shù),不然下個函數(shù)的 block 就會被替代.成功或者失敗的回調(diào)在圖片張數(shù)大于1時,永遠(yuǎn)不會被回調(diào)了.

3.如果要自己修改需求.一定要寫好邊界條件.遞歸在適當(dāng)?shù)臅r候返回,不然就會成死循環(huán)了.

4.全局的下標(biāo)標(biāo)識,在完成后一定要清零,不然在同個界面再次操作的時候,標(biāo)示還保留的上次的最大值,再次調(diào)用函數(shù),會拋出異常.數(shù)組越界.

三.保留數(shù)據(jù)的做法.

? ? ?這點筆者并沒有寫,就談?wù)勊悸?就是保留數(shù)據(jù).當(dāng)用戶點擊了保存后,應(yīng)該把數(shù)據(jù)保存到數(shù)據(jù)庫,在上傳服務(wù)器,這時候就不會讓提示失敗,我們會始終把數(shù)據(jù)上傳到服務(wù)器為止.我看在處理藍(lán)牙接受到的數(shù)據(jù)就是這樣處理的,應(yīng)為該數(shù)據(jù)為不保留性,過了就會沒有了,但是用戶要用這塊數(shù)據(jù),不能丟失用戶的數(shù)據(jù),所以我們應(yīng)該將此數(shù)據(jù)保留到數(shù)據(jù)庫,上傳服務(wù)器成功為止.用戶多張圖片感覺也是這樣,應(yīng)為這幾張圖片是用戶在自己的相冊精挑細(xì)選出來的,用戶想的就是要這圖片.不應(yīng)該就因為一些原因丟失用戶的數(shù)據(jù).喲感興趣的小伙伴可以試試.

今天就寫到這了.周六早晨就下雨,感覺挺舒服清爽的!

補(bǔ)丁:Demo 地址?2016/8/17

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容