ここで行われているように、AFURLSessionManager を使用してバックグラウンドで S3 に約 100 個の画像を 10 個の小さなバッチでアップロードしようとしています -バックグラウンド NSURLSession でアクティブなタスクの数を管理します
私は共有 NSURLSession を使用しており、いくつかのタスクが完了したときに、これに応じてタスクを追加しています。各ファイルの平均サイズは約 1.6 MB で、タスク キューごとに実行が保証されているタスクの数は 5 です。
タスクを追加するための私の方法は次のとおりです: (読みやすい要点としても利用可能)
- (void) addTasksToSessionWithTaskObject:(Task*)taskObject withSessionInitialisationNeeded:(BOOL) needed{
NSString *filePath = [[NSBundle mainBundle] pathForResource:pathForResourceFile ofType:resourceFileType];
S3PutObjectRequest *putObjectRequest = [[S3PutObjectRequest alloc] initWithKey:targetFileKey
inBucket:_bucketname];
putObjectRequest.cannedACL = [S3CannedACL publicReadWrite];
putObjectRequest.filename = filePath;
putObjectRequest.contentType = [resourceFileType isEqualToString:@"MOV"] ? @"movie/mov" : @"image/jpg";
putObjectRequest.endpoint = @"http://s3.amazonaws.com";
putObjectRequest.contentLength=[[[NSFileManager defaultManager]
attributesOfItemAtPath:filePath error:nil] fileSize];
putObjectRequest.delegate = self;
[putObjectRequest configureURLRequest];
NSMutableURLRequest *request = [s3Client signS3Request:putObjectRequest];
NSMutableURLRequest *request2 = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://s3.amazonaws.com/UploadTest/%@",taskObject.fileKey]]];
[request2 setHTTPMethod:request.HTTPMethod];
[request2 setAllHTTPHeaderFields:[request allHTTPHeaderFields]];
if(needed) {
sharedSession = [self backgroundSession];
}
NSURLSessionUploadTask *task = [sharedSession uploadTaskWithRequest:request2 fromFile:forFileUrl];
task.taskDescription = pathForResourceFile;
[currentlyActiveTaskIdArray addObject:@([task taskIdentifier])];
[task resume];
}
そして、これは私がデリゲートで行ったことです
- (void)URLSession:(NSURLSession *)sessionI task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error{
dispatch_async(dispatch_get_main_queue(), ^{
__block UIBackgroundTaskIdentifier bgTaskI = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTaskI];
}];
if([currentlyActiveTaskIdArray containsObject:@([task taskIdentifier])]){
[currentlyActiveTaskIdArray removeObject:@([task taskIdentifier])];
}
if(currentlyActiveTaskIdArray.count < LOWER_SLAB_FOR_TASKS + 1){
[self initiateS3UploadForSetOfTasksIsItBeginningOfUpload:NO];
}
[[UIApplication sharedApplication] endBackgroundTask:bgTaskI];
});
}
タスクを追加するコードは次のとおりです
- (void) initiateS3UploadForSetOfTasksIsItBeginningOfUpload:(BOOL)beginning{
int i=0;
for(Task *eachTaskObject in tasksArray){
if(i < numberOfTasksTobeAdded){
[self addTasksToSessionWithTaskObject:eachTaskObject WithSessionInitialisationNeeded:NO];
i++;
}
}
}
フォアグラウンド モードとバックグラウンド モードで 100 個のファイルを使用してテストを実行しています。フォアグラウンド モードでは、一貫した安定した一定の速度でファイルをアップロードし、最初の 3 分間で 90 個のファイルを完了し、残りの 10 個のファイルを 20 秒で完了します。
アプリをバックグラウンド モードで実行すると、最初の 90 個のファイルが 3 分間のフォアグラウンド ウィンドウと同じ速度でアップロードされ、その後速度が低下すると予想されますが、そうではありません。バックグラウンド モードでは、最初の 1 分間に 15 個のファイルをアップロードし、その後速度が低下し始めます。1 分、3 分、5 分、10 分、そして今は 17 分と、徐々に遅い間隔で 8 つのファイル バッチでアップロードを開始します。46 分で 65 ファイルになりました。
少なくとも最初の 3 分間は速度を維持するか、バックグラウンドで一定の速度を維持する方法はありますか?
更新:ここで Clay からのコメントに続いて、私は AFURLSessionManager から NSURLSession に切り替えました。なぜなら、彼が指摘するように、ブロックベースのコールバックを使用することは NSURLSession で非常に危険なビジネスだからです。さらに、私は HTTPMaximumConnectionsPerHost で遊んで、これを約 10 に設定しました。これにより、より良い結果が得られましたが、私が望むものにはほど遠いものでした。