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

項(xiàng)目需求:允許用戶可以選擇多張圖片上傳到服務(wù)器(使用的七牛云).
思路:
  1. 一開始想的是任務(wù)分發(fā),將所有圖片遍歷放到子線程中上傳,這樣N張圖片會(huì)同時(shí)上傳。但這樣有弊端:如果需要精確顯示上傳進(jìn)度,邏輯處理會(huì)比較復(fù)雜,同時(shí)因?yàn)椴皇亲约旱拇鎯?chǔ)服務(wù)器,不能自己根據(jù)用戶選擇的圖片順序存儲(chǔ)在服務(wù)器上(猜測(cè)是我們的服務(wù)器懶,不想寫)。
  2. 那就采用逐一上傳圖片的思路。如果某一張上傳成功,執(zhí)行下一張上傳任務(wù)。某一張上傳失敗,記錄失敗圖片下標(biāo)(可選擇重復(fù)上傳,或保存數(shù)據(jù)),繼續(xù)下一張上傳任務(wù).
代碼:GitHub
實(shí)現(xiàn):
@interface FGUploadImageManager ()

/**
 上傳失敗的數(shù)組
 */
@property (nonatomic, strong) NSMutableArray *failedIndexs;
/**
 上傳圖片數(shù)據(jù)
 */
@property (nonatomic, strong) NSArray *upLoadArray;
/**
  標(biāo)識(shí)的下標(biāo)
 */
@property (nonatomic, assign) NSUInteger currentIndex;
/**
 某一張圖片失敗次數(shù)
 */
@property (nonatomic, assign) NSInteger onceFailedCount;

@end
//單張圖片上傳失敗最大次數(shù)
const static NSInteger kMaxUploadCount = 3;
/**
 上傳多張圖片入口
 */
- (void)upLoadImageWithImageArray:(NSArray *)imageArray
{
    [self cleanData];
    //初始化數(shù)據(jù)
    self.failedIndexs = [NSMutableArray array];
    self.upLoadArray = [NSArray arrayWithArray:imageArray];
    [SVProgressHUD showWithStatus:@"正在上傳圖片..."];
    
    [self upLoadPhotosOnceCompletion:^(NSUInteger index, BOOL isSuccess) {
        if (isSuccess) {
            //添加上傳成功后的動(dòng)作...(刷新UI等)
            NSLog(@"上傳第%zd照片",index);
        }
        else {
            [self.failedIndexs addObject:@(index)];
        }
    } completeBlock:^{
        if (self.failedIndexs.count != 0) {
            NSMutableString *mutableString = [NSMutableString string];
            for (NSNumber *index in self.failedIndexs) {
                [mutableString appendFormat:@"第%@張",index];
            }
            [SVProgressHUD showErrorWithStatus:[NSString stringWithFormat:@"%@上傳失敗",mutableString]];
        }else{
            [SVProgressHUD showSuccessWithStatus:@"圖片全部上傳成功"];
        }
        [self cleanData];
    }];
}
/**
 *  遞歸上傳照片
 */
- (void)upLoadPhotosOnceCompletion:(void(^)(NSUInteger index,BOOL isSuccess))onceCompletion completeBlock:(void(^)(void))completeBlock{
    //根據(jù)下標(biāo),從數(shù)組中取出圖片,轉(zhuǎn)為二進(jìn)制數(shù)據(jù)
    NSData * data = UIImagePNGRepresentation(self.upLoadArray[self.currentIndex]);
    //發(fā)起網(wǎng)絡(luò)請(qǐng)求
    [[FGUploadHTTPRequest shareUpload] uploadPhotoAlbum:data uploadProgress:^(float percent) {
        //顯示上傳的進(jìn)度
        [SVProgressHUD showProgress:(CGFloat)(self.currentIndex + percent) / self.upLoadArray.count status:@"正在上傳中"];
    } completeBlock:^(BOOL isSuccess) {
        //如果上傳失敗,并且沒有超過最大上傳次數(shù),重新上傳
        if (!isSuccess) {
            self.onceFailedCount++;
            if (self.onceFailedCount < kMaxUploadCount) {
                [self upLoadPhotosOnceCompletion:onceCompletion completeBlock:completeBlock];
                return;
            }
        }
        //清空失敗次數(shù)
        self.onceFailedCount = 0;
        //記錄新的下標(biāo)index++
        self.currentIndex++;
        //回調(diào)一次的結(jié)果
        if (onceCompletion) onceCompletion(self.currentIndex,isSuccess);
        //判斷是否上傳完畢
        if (self.currentIndex == self.upLoadArray.count) {
            //如果是已經(jīng)上傳完了,結(jié)束
            self.currentIndex = 0 ;
            if (completeBlock) completeBlock();
        }
        else
        {
            //如果還沒上傳完成,繼續(xù)下一次上傳
            [self upLoadPhotosOnceCompletion:onceCompletion completeBlock:completeBlock];
        }
    }];
}

1.當(dāng)某張上傳失敗,會(huì)嘗試上傳kMaxUploadCount次,如果仍然失敗,那就放棄本張圖片,繼續(xù)上傳下一張圖片。
2.全局的下標(biāo)標(biāo)識(shí),在完成后一定要清零,不然在同個(gè)界面再次操作的時(shí)候,標(biāo)示還保留的上次的最大值,再次調(diào)用函數(shù),會(huì)拋出異常.數(shù)組越界.
3.如果要自己修改需求.一定要寫好邊界條件.遞歸在適當(dāng)?shù)臅r(shí)候返回,不然就會(huì)成死循環(huán)了.

保留數(shù)據(jù)持續(xù)上傳的做法:

如果存在未上傳成功的圖片,我們可以將圖片扔給一個(gè)始終存在的單例或者考慮將圖片數(shù)據(jù)寫入數(shù)據(jù)庫(kù)中,這樣保證了圖片數(shù)據(jù)可以一直存在。我們要做的就是講這份數(shù)據(jù)一直不停的上傳給服務(wù)器。

用戶多張圖片感覺也是這樣,應(yīng)為這幾張圖片是用戶在自己的相冊(cè)精挑細(xì)選出來(lái)的,用戶想的就是要這圖片。不應(yīng)該就因?yàn)橐恍┰騺G失用戶的數(shù)據(jù)。當(dāng)然這是產(chǎn)品考慮的一些內(nèi)容。

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

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