gpt4 book ai didi

ios - 在后台使用 NSURLSession 一个一个地下载 100 个文件的列表

转载 作者:可可西里 更新时间:2023-11-01 04:57:51 25 4
gpt4 key购买 nike

我已经使用 NSURLSession 实现了一个针对 iOS 7+ 的下载管理器应用程序。下载管理器有一个排队的文件列表,要按优先顺序下载。当应用程序处于后台并且代理调用被正确调用时,下载工作正常。但是当应用程序进入后台时,即使下载完成也需要太多时间

NSURLSession delegate:- **URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL

接到电话。有时根本不会调用委托(delegate),当我来到前台时,就会调用下载任务委托(delegate)。这种延迟有什么原因吗?

最佳答案

我有一个非常相似的问题,后台任务将开始但随后似乎暂停了。当应用程序返回前台时,任务将完成。

我通过记录 -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite 的输出来验证情况是否如此: (int64_t)totalBytesExpectedToWrite

我发现解决这个问题的方法是如何存储、处理和执行完成处理程序。

在我的例子中,这个过程开始于

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{

[self.fmStore performBackgroundRefresh:^(UIBackgroundFetchResult result) {

//Set application badge if new data is available
if (result==UIBackgroundFetchResultNewData) [UIApplication sharedApplication].applicationIconBadgeNumber++;
completionHandler(result);

}];
}

远程通知开始下载过程的地方。

管理下载的方法根据新数据的可用性返回一个值

-(void)performBackgroundRefresh:(void (^)(UIBackgroundFetchResult))completion{
if(newData) completion(UIBackgroundFetchResultNewData);
else completion(UIBackgroundFetchResultNoData);
}

此时它返回到存储完成处理程序的ApplicationDelegate

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{
//Store completion handler for background session
self.sessionCompletionHandler=completionHandler;
}

最后,执行这段代码,调用完成处理程序并创建适当的通知

- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
[session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
if (![downloadTasks count]) {


FM_AppDelegate *appDelegate=(FM_AppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate.sessionCompletionHandler) {
void (^completionHandler)() = appDelegate.sessionCompletionHandler;
appDelegate.sessionCompletionHandler = nil;
completionHandler();
}
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"ContentRefreshNotification" object:Nil];
}];
}
}];
}

这个来回过程在我的例子中发生,因为 NSURLSession 存在于一个对象中,该对象是 ApplicationDelegate 的一个属性。如果您将 NSURLSession 实现为 ApplicationDelegate 本身的属性,那么所有这些代码都将存在于同一个文件中。

希望这对您有所帮助,但如果您需要更多信息,请参阅这两个教程 12因为我的代码是基于我在这些文章中读到的内容。

关于ios - 在后台使用 NSURLSession 一个一个地下载 100 个文件的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23356118/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com