7

バックグラウンドでファイルをダウンロードするように構成されています.ダウンロードタスクがユーザーによってキャンセルされた場合、すべてのデータが削除され、ファイルが使用していたストレージスペースが解放されますが、アプリがマルチタスクドックから閉じられた場合NSURLSession、ダウンロードNSURLSessionDownloadTaskタスクが終了してエラーが発生しますが、データは削除されておらず、ファイルの一時データはまだストレージ領域を占有しており、解放されていません。スペースを解放するにはどうすればよいですか?

これは私のNSURLSession構成とエラー処理です:

- (NSURLSession *)backgroundSession {
    static NSURLSession *session = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        NSURLSessionConfiguration *configuration;
        if ([[UIDevice currentDevice].systemVersion hasPrefix:@"7"]) configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.visyon.pr"];
        else configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.visyon.pr"];
        configuration.sessionSendsLaunchEvents =YES;

        session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];

    });
    return session; }


- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {


if (error == nil) {
    NSLog(@"Task: %@ completed successfully", task );
} else {
   // [self hideActivity];
   // [self showAlertBoxErrorDownload];
    NSLog(@"Task: %@ completed with error: %@, %lu", task, [error localizedDescription], (long)error.code);

}    self.downloadTask = nil; }
4

3 に答える 3

6

10 日以上の試行錯誤の末、私は解決策を見つけました。まず、ユーザーがアプリを閉じて、バックグラウンドでアクティブなダウンロードが行われている場合のシナリオが 2 つあります。この場合、ダウンロード タスクを考慮に入れてください。再開することを意図したものではありません。

シナリオ 1. ユーザーがアプリを閉じてもまだアクティブな場合、- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)errorが呼び出され、ダウンロードに使用されていた一時ファイルがアプリの一時ディレクトリに直接移動します。この場合、- (void)applicationWillTerminate:(UIApplication *)applicationが呼び出されますが、ダウンロード タスクのデリゲートです。が最初に呼び出されます。この場合の解決策は、アプリが開かれるたびに一時ディレクトリをクリーンアップするコードを実装するか、iOS が一時フォルダーをクリーンアップできるようにすることです。

iOS はいつローカル アプリの ./tmp ディレクトリを消去しますか?

シナリオ 2. ユーザーがバックグラウンド モードでアプリを閉じると、アプリは終了し、次にアプリを開くと - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)errorが呼び出され、ダウンロードに使用していた一時ファイルがNSCachesDirectory次のディレクトリに保存されます。

var/mobile/Containers/Data/Application/CA21-B6E8-3305A39/Library/Caches/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/CFNetworkDownload_M5o8Su.tmp

一時ファイルは、次回の新しいダウンロード時にアプリの一時ディレクトリに移動されます。

ここでの解決策は、が起動さCaches/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/ れるとすぐに すべての一時ファイルを削除するコードを実装することです。- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error

から一時ファイルを削除するためのコードは次のNSCachesDirectoryとおりです。

    NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[path stringByAppendingPathComponent:@"/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/"] error:nil];
    for (NSString *string in array) {
        [[NSFileManager defaultManager] removeItemAtPath:[path stringByAppendingPathComponent:[NSString stringWithFormat:@"/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/%@",  string]] error:nil];
    }

ただし、このシナリオでのみ機能するため、起動するたびにアプリの一時ディレクトリをクリーンアップするコードを実装するか、iOS に一時フォルダーをクリーンアップさせて、両方のシナリオで機能するようにすることをお勧めします。

アプリの一時ディレクトリを消去する方法のコードは次のとおりです。

NSString *path = NSTemporaryDirectory();
NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
for (NSString *string in array) {
    [[NSFileManager defaultManager] removeItemAtPath:[path stringByAppendingPathComponent:string] error:nil];
}
于 2015-08-04T11:34:16.243 に答える
0

と呼ばれる AppDelegate にメソッドがあり- (void)applicationWillTerminate:(UIApplication *)applicationます。[NSURLSessionDownloadTask cancel];そこからいずれかの呼び出しを試すことができます。または、アプリを閉じたときに進行中のダウンロードがあったことをアプリに示すフラグを設定し、次にアプリを開いたときにデータを削除してみてください。

于 2015-07-30T22:17:11.977 に答える