我有一个用于计算成功下载的变量@property(nonatomic)int downloadsSuccessfulCounter;.在下载文件时,我禁用了下载按钮.当计数器等于下载列表大小时,我再次启用该按钮并将计数器设置为0.我在方法中执行此 *** 作:
-(voID)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask dIDFinishDownloadingToURL:(NSURL *)location {... [[NSOperationQueue mainQueue] addOperationWithBlock:^ { downloadsSuccessfulCounter++; if(downloadsSuccessfulCounter == self.downloadList.count) { NSLog(@"All downloads finished"); [self.syncbutton setEnabled:YES]; downloadsSuccessfulCounter = 0; } }];
}
一切都运行正常,但是当我再次打开VIEwController时,我收到消息一个带有标识符com.myApp的后台URLSession已经存在!计数器未设置为0,UI元素(UIbuttons,UILabels)没有响应.
我想问题是因为NSURLSession仍然是开放的,但我不确定它是如何工作的.
我已经尝试了所有教程,但其中99%仅用于下载1个文件,不超过1个…
有任何想法吗?
这是我的代码:
... @property (nonatomic,strong) NSURLSession *session;... - (voID)vIEwDIDLoad { [super vIEwDIDLoad]; appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; self.downloadList = [[NSMutableArray alloc] init]; NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.myApp"]; sessionConfiguration.httpMaximumConnectionsPerHost = 5; self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];}
当我按下Download buttonI时调用此方法(
我有一个包含NSURLSessionDownloadTask的可下载对象:
-(voID)startDownload { for (int i=0; i<[self.downloadList count]; i++) { Downloadable *d = [self.downloadList objectAtIndex:i]; if (!d.isDownloading) { if (d.taskIDentifIEr == -1) { d.downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:d.downloadSource]]; }else { d.downloadTask = [self.session downloadTaskWithResumeData:fdi.taskResumeData]; } d.taskIDentifIEr = d.downloadTask.taskIDentifIEr; [d.downloadTask resume]; d.isDownloading = YES; } }}
当应用程序处于后台时:
-(voID)URLSessionDIDFinishEventsForBackgroundURLSession:(NSURLSession *)session{ AppDelegate *appDelegate = [UIApplication sharedApplication].delegate; [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks,NSArray *uploadTasks,NSArray *downloadTasks) { if ([downloadTasks count] == 0) { if (appDelegate.backgroundTransferCompletionHandler != nil) { voID(^completionHandler)() = appDelegate.backgroundTransferCompletionHandler; appDelegate.backgroundTransferCompletionHandler = nil; [[NSOperationQueue mainQueue] addOperationWithBlock:^{ completionHandler(); UIlocalnotification *localnotification = [[UIlocalnotification alloc] init]; localnotification.alertbody = @"All files downloaded"; [[UIApplication sharedApplication] presentlocalnotificationNow:localnotification]; }]; } } }];}解决方法 因此,正如我在评论中提到的,问题是每个文件都需要一个唯一的NSURLSession,并且每个NSURLSession都需要一个具有唯一标识符的NSURLSessionConfiguration.
我认为你很亲密 – 在某些方面可能比我更合适……
您只需要创建一个结构,将唯一ID传递给唯一的配置,以填充唯一的会话(比如快10倍).
这是我做的:
/ *
*检索要下载的文件列表
*还使用该列表的大小来实例化项目
*在我的情况下,我加载一个字符返回的文本文件,其中包含我要下载的文件的名称
* /
- (voID) getMediaList { Nsstring *List = @"http://myserver/media_List.txt"; NSURLSession *session = [NSURLSession sharedSession]; // <-- BASIC session [[session dataTaskWithURL:[NSURL URLWithString:List] completionHandler:^(NSData *data,NSURLResponse *response,NSError *error) { Nsstring *stringFromData = [[Nsstring alloc] initWithData: data enCoding: NSUTF8StringEnCoding]; // Populate Arrays REMOTE_MEDIA_file_PATHS = [stringFromData componentsSeparatedByString:@"\n"]; [self instantiateURLSessions:[REMOTE_MEDIA_file_PATHS count]]; // Start First file [self getfile:[REMOTE_MEDIA_file_PATHS objectAtIndex:downloadCounter]:downloadCounter]; // this variable is 0 at the start }] resume];}
/ *
*这将配置和会话数组设置为适当的大小
*它还为每个人提供唯一的ID
* /
- (voID) instantiateURLSessions : (int) size { NSMutableArray *configurations = [NSMutableArray array]; NSMutableArray *sessions = [NSMutableArray array]; for (int i = 0; i < size; i++) { Nsstring *index = [Nsstring stringWithFormat:@"%i",i]; Nsstring *UniqueIDentifIEr = @"MyAppBackgroundSessionIDentifIEr_"; UniqueIDentifIEr = [UniqueIDentifIEr stringByAppendingString:index]; [configurations addobject: [NSURLSessionConfiguration backgroundSessionConfigurationWithIDentifIEr:UniqueIDentifIEr]]; [sessions addobject:[NSURLSession sessionWithConfiguration: [configurations objectAtIndex:i] delegate: self delegateQueue: [NSOperationQueue mainQueue]]]; } NSURL_BACKGROUND_CONfigURATIONS = [NSArray arrayWithArray:configurations]; NSURL_BACKGROUND_SESSIONS = [NSArray arrayWithArray:sessions];}
/ *
*这将根据数组的索引为每个文件设置下载任务
*它还连接到实际文件的路径
* /
- (voID) getfile : (Nsstring*) file :(int) index { Nsstring *fullPathTofile = REMOTE_MEDIA_PATH; // Path To Server With files fullPathTofile = [fullPathTofile stringByAppendingString:file]; NSURL *url = [NSURL URLWithString:fullPathTofile]; NSURLSessionDownloadTask *downloadTask = [[NSURL_BACKGROUND_SESSIONS objectAtIndex:index ] downloadTaskWithURL: url]; [downloadTask resume];}
/ *
*最后,在我的委托方法中,在下载完成后(从临时数据移出文件后),我检查是否已完成,如果没有再次使用更新的索引计数器调用getfiles方法
* /
-(voID)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask dIDFinishDownloadingToURL:(NSURL *)location{ // Get the documents directory URL NSArray *paths = NSSearchPathForDirectorIEsInDomains(NSdocumentDirectory,NSUserDomainMask,YES); Nsstring *documentsDirectory = [paths objectAtIndex:0]; Nsstring *dataPath = [documentsDirectory stringByAppendingPathComponent:LOCAL_MEDIA_PATH]; NSURL *customDirectory = [NSURL fileURLWithPath:dataPath]; // Get the file name and create a destination URL Nsstring *sendingfilename = [downloadTask.originalRequest.URL lastPathComponent]; NSURL *destinationUrl = [customDirectory URLByAppendingPathComponent:sendingfilename]; // Move the file NSError *error = nil; NSfileManager *fileManager = [NSfileManager defaultManager]; if ([fileManager moveItemAtURL:location toURL:destinationUrl error: &error]) { // List [self ListCustomDirectory]; if(downloadCounter < [REMOTE_MEDIA_file_PATHS count] -1) { // Increment Counter downloadCounter++; // Start Next file [self getfile:[REMOTE_MEDIA_file_PATHS objectAtIndex:downloadCounter]:downloadCounter]; } else { // FINISH YOUR OPERATION / NOTIFY USER / ETC } } else { NSLog(@"damn. Error %@",error); // Do Something Intelligent Here } }总结
以上是内存溢出为你收集整理的ios7 – iOS 7 NSURLSession在后台下载多个文件全部内容,希望文章能够帮你解决ios7 – iOS 7 NSURLSession在后台下载多个文件所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)