我的NSURLSessionDelegate方法不会在后台下载期间被调用 [英] My NSURLSessionDelegate methods are not getting called during a background download

查看:377
本文介绍了我的NSURLSessionDelegate方法不会在后台下载期间被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用 NSURLSession 设置下载,它将在后台继续。
我有一个单例类 DownloadManager ,它构建了 NSURLSession 并启动一个下载任务,如下所示: / p>

I'm trying to set up a download using NSURLSession that will continue in the background. I have a singleton class called DownloadManager which builds the NSURLSession and starts a download task like this:

- (id)init
{
    self = [super init];
    if (self) {
        self.queue = [[NSOperationQueue alloc] init];
        self.queue.maxConcurrentOperationCount = 1;

        // Initialize the background session.
        self.session = [self backgroundSession];
    }
    return self;
}

- (NSURLSession *)backgroundSession
{
    static NSURLSession *session = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.mycompany.myapp.BackgroundSession"];
        session = [NSURLSession sessionWithConfiguration:sessionConfiguration
                                                delegate:self
                                           delegateQueue:self.queue];
    });
    return session;
}

- (void)startDownload:(Download *)download
{
    NSURL *remoteURL = ...
    NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:remoteURL];
    [task resume];
}



我实现了 NSURLSessionDelegate NSURLSessionDownloadDelegate 方法,包括 URLSessionDidFinishEventsForBackgroundURLSession:。此外,我的应用程序委托实现 application:handleEventsForBackgroundURLSession:completionHandler:

I've implemented the NSURLSessionDelegate and NSURLSessionDownloadDelegate methods including URLSessionDidFinishEventsForBackgroundURLSession:. Additionally, my application delegate implements application:handleEventsForBackgroundURLSession:completionHandler:.

但是,当我在开始下载后通过按主页按钮将应用程序移动到后台时,所有下载委托方法都会停止触发,并且应用程序: handleEventsForBackgroundURLSession:completionHandler:从未被调用。下载继续,如果我等待足够的时间完成,然后 URLSession:downloadTask:didFinishDownloadingToURL:被称为我的应用程序回到前台的那一刻。这意味着我不能在后台进行任何后处理(例如保存到核心数据,开始新的下载等)。

However, when I move my application to the background by pressing the home button after starting a download, all download delegate methods stop firing and application:handleEventsForBackgroundURLSession:completionHandler: is never called. The download continues, and if I wait long enough for it to finish then URLSession:downloadTask:didFinishDownloadingToURL: is called the moment I bring my app back to the foreground. This means that I can't do any post-processing in the background (e.g. save to core data, start a new download, etc.).

我试过添加'background fetch'后台模式到我的plist,如果需要,我尝试更改我的标识符用于创建 NSURLSessionConfiguration 后台配置,如此答案

I tried adding the 'Background fetch' background mode to my plist in case that was required, and I tried changing my the identifier used to create the NSURLSessionConfiguration background configuration as suggested in this answer. Have I made a mistake in setting this up, or am I not supposed to be able to handle download delegate events in the background?

推荐答案

至于为什么你看不到 handleEventsForBackgroundURLSession ,我只能想到一对夫妇)可能性:

As to why you're not seeing handleEventsForBackgroundURLSession called, I can only think of a couple (admittedly, unlikely) possibilities:


  1. 确保 handleEventsForBackgroundURLSession 你的应用程序委托是绝对正确的(大小写,拼写等)。一个小错字不会产生任何警告,但会导致它不被调用。所以它应该是:

  1. Make sure that the signature of the handleEventsForBackgroundURLSession in your app delegate is absolutely correct (capitalization, spelling, etc.). A minor typo will not generate any warning, but it will result in its not getting called. So it should be:

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler
{
    // save the completionHandler here
}


  • 您确定所有的背景下载已完成吗?如果其中一个由于某种原因挂起或失败,这将阻止触发后台会话的完成,并且因为委托方法仅在一切完成后调用,这意味着您的应用程序不会被激活。

  • Are you sure all of your background downloads are finishing? If one of them hangs or fails for some reason, that will prevent the completion of the background session to be triggered, and because the delegate method is only called when everything is done, that means that your app will not be activated. I'd carefully check that all of the downloads have finished.

    您是否检查过设备的控制台? (你可以看到这一点,如果你去Xcode管理器的设备部分。)有时有一些有趣的诊断错误消息,后台守护程序将为您记录。检查,如果你还没有。

    Have you checked the device's console? (You can see this if you go to the "Devices" section of the Xcode "Organizer".) Sometimes there are interesting diagnostic error messages which the background daemon will log for you. Check that out if you haven't already. Lots of interesting stuff there.

    如果您通过SpringBoard手动杀死应用程序(双击物理主页按钮,按住应用程序图标,红x),这将杀死后台下载任务,因此您不会收到通知,所有的下载完成。请确保您实现 URLSession:task:didCompleteWithError:,以便您可以看到此错误(以及任何其他错误)。

    If you manually kill the app via SpringBoard (double tapping on physical home button, hold down app icon until its jiggling, click on red "x"), that will kill the background download tasks, and therefore you won't get notification that all of the downloads are done. Make sure you implement URLSession:task:didCompleteWithError: so you can see this error (and any others).

    然而,如果我编程崩溃的应用程序,如WWDC 2013视频中所示基础版网络,或者如果它被系统终止,则后台下载正确完成,并且正确调用了应用程序委托方法。

    If, however, I programmatically crash the app as illustrated in the WWDC 2013 video What’s New in Foundation Networking, or if it is terminated by the system, then the background downloads finish correctly and the app delegate method is getting called correctly.

    只是几个想法要考虑。

    这篇关于我的NSURLSessionDelegate方法不会在后台下载期间被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆