七牛云每上傳一張圖片都要從服務端請求token,和key不能像阿里云那樣在客戶端sdk中設置路徑。如果要上傳多張圖片,就要多次網絡請求,得到token后再上傳。如果我要多張圖片全部上傳完再做某個操作,就會很麻煩。
解決思路:
//創建隊列組
dispatch_group_t group = dispatch_group_create();
//創建隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//隊列中添加任務
dispatch_group_async(group, queue, ^{
});
//隊列組結束通知
dispatch_group_notify(_group, dispatch_get_main_queue(), ^{
};
基本思路就是創建一個隊列組、一個隊列,然后循環添加上傳任務到隊列組中的隊列中去,然后全部結束后在隊列組的通知回調中去操作接下來的任務。
重點:
通知group,下面的任務馬上要放到group中執行了
dispatch_group_enter
通知group,任務完成了,該任務要從group中移除了
dispatch_group_leave:
dispatch_group_async(group, queue, ^{
//在這個方法中,如果執行異步任務,比如用網絡請求,執行請求后就算走完了,不會等請求回調完成
//這樣結束通知dispatch_group_notify就不準確了
});
因此我們就要用到上面那兩個方法了,正確的做法是:
dispatch_group_t group = dispatch_group_create();
//創建隊列
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) {
//結束的時候標記結束
dispatch_group_leave(group);
}
else {
_isFailed = YES;
NSLog(@"upload object failed, error: %@" , info.error);
//結束的時候標記結束
dispatch_group_leave(group);
}
} option:uploadOption];
}
無論上傳成功還是失敗都要標記結束,網絡請求失敗也要標記結束(也可以當嘗試n次請求后任然失敗后標記),這樣以后我們就可以在
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
};
這個方法中準確的獲取到全部上傳結束的回調,我們可以在這個方法中做接下來的處理了。上面的代碼都只能算是偽代碼,實際開發中還要自己完善,以及添加一些邏輯比如上傳失敗,請求token失敗,最多嘗試次數等處理,主要知道這個流程和思路就可以了。