在iOS中下载背景中的大量文件

Rot*_*ten 6 objective-c ios nsurlsession nsurlsessiondownloadtask

我有一个应用程序,我必须下载大量文件,从400到900文件,总共约1GB.

实现这一目标的最佳方法是哪种?

  1. 其中一项NSURLSession任务入围了吗?
  2. 一个NSURLSession并按包排队任务(例如10乘10)?
  3. 多个NSURLSession不同的队列?

实际上我有一个NSURLSession所有任务(每个文件一个)排队,但有时我得到一个Lost connection to background transfer service.

这是我的代码:

if([[UIDevice currentDevice] isMultitaskingSupported])
{
    __block UIBackgroundTaskIdentifier bgTask;

    UIApplication *application = [UIApplication sharedApplication];

    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{

        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSString *uuidString;
        CFUUIDRef uuid = CFUUIDCreate(nil);
        uuidString = CFBridgingRelease(CFUUIDCreateString(nil, uuid));
        CFRelease(uuid);
        //            }

        NSURLSessionConfiguration *sessionConfiguration;

        if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0"))
        {
            sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.fiveflamesmobile.bakgroundDownload"];
        }
        else
        {
            sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.fiveflamesmobile.bakgroundDownload"];
        }
        sessionConfiguration.HTTPMaximumConnectionsPerHost = 5;
        sessionConfiguration.sessionSendsLaunchEvents = YES;
        sessionConfiguration.discretionary = YES;
        sessionConfiguration.timeoutIntervalForResource = 0; //NO timeout
        sessionConfiguration.timeoutIntervalForRequest = 0; //No timeout
        sessionConfiguration.networkServiceType = NSURLNetworkServiceTypeBackground;

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

        NSLog(@"##### ------- Sesion created succesfully");

        //    [self batchDownloading];

        for (id<FFDownloadFileProtocol> file in self.selectedCatalogProducto.downloadInfo.arrayFiles)
        {
            [self startDownloadFile:file];
        }

        NSLog(@"##### ------- Download tasks created successfully ------");

        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}

}
Run Code Online (Sandbox Code Playgroud)

小智 1

一个 NSURLSession - 因为您只想处理一次基于会话的事情(例如身份验证)。

一个 NSOperationQueue - 同时运行多个操作。(参见属性操作计数)。第一次实现 NSOperation 可能有点棘手,但我确信这将是您最好的选择。 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSOperationQueue_class/index.html

http://nshipster.com/nsoperation/

哦,顺便说一句,这是一种高度面向对象的方法,这总是很好 =)

  • 不不不!我非常喜欢将网络请求包装在“NSOperation”中,但这是唯一一种你绝对不会这样做的场景。后台会话配置是一种请求在应用程序终止后以及“NSOperationQueue”及其关联的“NSOperation”对象被销毁后继续运行很长时间的配置。另外,与标准会话配置对象不同,在标准会话配置对象中,“maxConcurrentOperationCount”提供了真正的价值,但在这里它只是碍事。对于后台会话,您希望立即实例化所有下载请求! (3认同)