2014-11-21 87 views
5

我有一个应用程序,我必须下载大量的文件,从400到900个文件,总共大约1GB。在iOS中下载大量文件在后台iOS

哪个是最好的方法来完成这个?

  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; 
    }); 
} 

} 
+0

'一个NSURLSession和排队的任务由包(10×10为例)? '听起来不错。 – 2014-11-21 13:19:46

+0

@AnoopVaidya你为什么这么说?他应该创建单个后台会话并将其下载任务添加到该会话中。我认为10x10方法没有价值。 – Rob 2014-11-21 13:45:26

+0

你是否可以下载后台的所有文件? – Mahesh 2016-06-03 15:06:17

回答

1

一个NSURLSession - 因为你只需要处理基于会话的事情只是一次(AUTH为例)。

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

http://nshipster.com/nsoperation/

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

+2

不,不,不!我是'NSOperation'中包装网络请求的巨大粉丝,但这是唯一的情况,你绝对不会这样做。后台会话配置是指在应用程序终止后以及'NSOperationQueue'及其关联的'NSOperation'对象被销毁后,请求继续运行很长时间的配置。此外,与标准会话配置对象不同,“maxConcurrentOperationCount”提供了真正的价值,在这里它只是挡道而已。通过后台会话,您想要立即实例化所有下载请求! – Rob 2014-11-21 22:48:18

+0

好的,这是很有道理的。这样,即使应用程序暂停,网络请求应继续加载。对?可悲的是,由于那个人需要有两种不同的方式来实现下载。操作方式只适用于后台会话,对吧? – fat 2014-11-22 09:27:00

+0

不仅在应用程序暂停时,而且即使在应用程序完全终止后(例如,如果操作系统由于内存压力而抛弃它),后台任务也会继续运行。后台守护进程知道的唯一事情就是任务,任何操作队列(以及队列中的任何待处理事项)都将很快消失。所以操作队列对于前台会话来说非常棒,但只会干扰后台会话。所以“操作方式只适用于”_non-background_(即默认或临时)会话。 (我想这就是你想说的,哈哈。) – Rob 2014-11-22 10:02:26