七牛云每上傳一張圖片都要從服務(wù)端請求token,和key不能像阿里云那樣在客戶端sdk中設(shè)置路徑。如果要上傳多張圖片,就要多次網(wǎng)絡(luò)請求,得到token后再上傳。如果我要多張圖片全部上傳完再做某個操作,就會很麻煩。
解決思路:
//創(chuàng)建隊列組
dispatch_group_t group = dispatch_group_create();
//創(chuàng)建隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//隊列中添加任務(wù)
dispatch_group_async(group, queue, ^{
});
//隊列組結(jié)束通知
dispatch_group_notify(_group, dispatch_get_main_queue(), ^{
};
基本思路就是創(chuàng)建一個隊列組、一個隊列,然后循環(huán)添加上傳任務(wù)到隊列組中的隊列中去,然后全部結(jié)束后在隊列組的通知回調(diào)中去操作接下來的任務(wù)。
重點:
通知group,下面的任務(wù)馬上要放到group中執(zhí)行了
dispatch_group_enter
通知group,任務(wù)完成了,該任務(wù)要從group中移除了
dispatch_group_leave:
dispatch_group_async(group, queue, ^{
//在這個方法中,如果執(zhí)行異步任務(wù),比如用網(wǎng)絡(luò)請求,執(zhí)行請求后就算走完了,不會等請求回調(diào)完成
//這樣結(jié)束通知dispatch_group_notify就不準確了
});
因此我們就要用到上面那兩個方法了,正確的做法是:
dispatch_group_t group = dispatch_group_create();
//創(chuàng)建隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < images.count; i++) {
dispatch_group_async(group, queue, ^{
[self requestToken];
});
}
- (void)requestToken {
//在開始的時候標記開始
dispatch_group_enter(_group);
[self.manager GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//獲取到token 和 key
[weakSelf uploadWithToken:token key:key];
}];
}
- (void)uploadWithToken:(NSString *)token key:(NSString *)key {
if (!_upManager) {
QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) {
builder.zone = [QNZone zone1];
}];
_upManager = [[QNUploadManager alloc] initWithConfiguration:config];
}
[_upManager putData:imageData key:key token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
//如果有失敗,取消上傳中的option
if (_isFailed) {
[uploadOption cancellationSignal];
}
NSLog(@"%@",info);
if (info.ok) {
//結(jié)束的時候標記結(jié)束
dispatch_group_leave(group);
}
else {
_isFailed = YES;
NSLog(@"upload object failed, error: %@" , info.error);
//結(jié)束的時候標記結(jié)束
dispatch_group_leave(group);
}
} option:uploadOption];
}
無論上傳成功還是失敗都要標記結(jié)束,網(wǎng)絡(luò)請求失敗也要標記結(jié)束(也可以當嘗試n次請求后任然失敗后標記),這樣以后我們就可以在
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
};
這個方法中準確的獲取到全部上傳結(jié)束的回調(diào),我們可以在這個方法中做接下來的處理了。上面的代碼都只能算是偽代碼,實際開發(fā)中還要自己完善,以及添加一些邏輯比如上傳失敗,請求token失敗,最多嘗試次數(shù)等處理,主要知道這個流程和思路就可以了。