NSURLSession 后台下载不起作用

Posted

技术标签:

【中文标题】NSURLSession 后台下载不起作用【英文标题】:NSURLSession background download not working 【发布时间】:2017-02-13 10:43:02 【问题描述】:

我正在尝试使用NSURLnsurlsessiontask 的后台会话下载一些文件。当应用程序在调试模式下运行时(当设备连接到 Xcode 时),一切都像魅力一样工作,当从 Xcode 中拔出设备 (iPad) 时,一切都不起作用。

我正在使用 Xcode 7.3.1 和 ios 9.3.5。我已经花了数周时间追踪这种奇怪的行为,但没有任何突破。可能是我错过了一些实现后台下载的东西。 最近将 Xcode 升级到 8.1.2,将 iOS 升级到 10.2.1,假设升级可能会解决问题,但事实并非如此。

【问题讨论】:

用您的代码更新您的问题,以便轻松找到您面临的一些错误或任何类型的错误 添加有助于了解您做错了什么的代码? 你应该使用 NSURLSessionDownloadTask 而不是 NSURLSessionTask 来下载文件。请显示代码。否则,这只是一场永远不会结束的猜谜游戏。 @GeneCode 我只使用了 NSURLSessionDownloadTask。奇怪的部分是我编写的任何代码,我的应用程序在后台下载多个文件,但只有当它连接到 Xcode 时,即从 Xcode 运行时。我的代码分散在不同的文件中,很难分享,我会尝试分享一些主要文件的代码。 如果你不分享你的代码而不是我们如何解决你的问题。 【参考方案1】:

参考以下链接并按照步骤操作

https://www.appcoda.com/background-transfer-service-ios7/

  -(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;

// Check if all download tasks have been finished.
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) 
    if ([downloadTasks count] == 0) 
        if (appDelegate.backgroundTransferCompletionHandler != nil) 
            // Copy locally the completion handler.
            void(^completionHandler)() = appDelegate.backgroundTransferCompletionHandler;

            // Make nil the backgroundTransferCompletionHandler.
            appDelegate.backgroundTransferCompletionHandler = nil;

            [[NSOperationQueue mainQueue] addOperationWithBlock:^
                // Call the completion handler to tell the system that there are no other background transfers.
                completionHandler();

                // Show a local notification when all downloads are over.
                UILocalNotification *localNotification = [[UILocalNotification alloc] init];
                localNotification.alertBody = @"All files have been downloaded!";
                [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
            ];
        
    
];

【讨论】:

欢迎提供解决方案链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted.【参考方案2】:

检查我的工作代码,

NSURL *url = [NSURL URLWithString:imageURL];
NSURLSessionTask *_imageDownloadTask = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) 
    if (data) 
           //Here you can read your files from data
        if (image) 
            dispatch_async(dispatch_get_main_queue(), ^
                  //Save your files here for cache purpose
                @try 
                    //You can handle onDownloadFinishWithFile: here too using delegate protocol 
                
                @catch (NSException *exception) 
                          NSLog(@"%@", exception.reason);
                
                @finally 
                  // Defines a block of related code that is subsequently executed whether an exception is thrown or not.
                
            );
        
    
];
[_imageDownloadTask resume]; 

[注意:我正在使用上面的代码下载图片]。

【讨论】:

【参考方案3】:

检查代码的其他部分是否有后台任务(后台任务由类似这样的东西 (UIApplication.beginBackgroundTask (expirationHandler: ...)) 启动。

我遇到过从applicationDidEnterBackground事件创建后台任务的情况:后台任务调用完成回调UIApplication.endBackgroundTask(...)失败,结果行为和你描述的症状一样:后台应用未连接到 Xcode 时下载失败。`

(这是XCode11.3,iOS13.3)

【讨论】:

【参考方案4】:

在项目导航器中,选择顶部的项目目标。接下来,在主窗口中单击功能选项卡,您只需使用开关按钮即可启用或禁用的所有功能都将显示在那里。其中,找到Background Modes区域(倒数第二个),点击其右侧的开关按钮即可开启。

然后切换“后台获取”。

【讨论】:

【参考方案5】:

确保检查功能中后台模式下的后台获取。

【讨论】:

Background fetch 和 NSURLSession 后台模式是两个完全不同的东西。

以上是关于NSURLSession 后台下载不起作用的主要内容,如果未能解决你的问题,请参考以下文章

NSURLSession“完成处理程序”内的导航不起作用

更改 NSURLCache 内存和磁盘容量不起作用

调用 http:// 在 ios 9 中不起作用 [重复]

后台获取 performFetchWithCompletionHandler 不起作用?

iOS后台获取不起作用

AFNetworking 3.0 后台上传不起作用