在 App 终止后继续 NSURLConnection

Continue a NSURLConnection after the App has been terminated

我想知道如何在应用程序终止时继续在前台启动的异步 NSURLConnection。 目前,当应用程序进入后台时,我正在启动一个 NSURLConnection 。只要用户比连接慢,当他想终止应用程序时,这就可以正常工作。但是当用户比它快时,就无法建立连接。 这是我的代码:

// AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    AnObject *newObject = [[AnObject alloc] init];
    [newObject InactiveApp];
}

// AnObject.m
- (void)InactiveApp
{
    self.backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];

    // setting up the NSURLRequest
    // [...]

    dispatch_async(dispatch_get_main_queue(), ^
    {
        [NSURLConnection connectionWithRequest:request delegate:self];
    });
}
// delegate functions, endBackgroundTask-closing, etc. is following

不幸的是,这不起作用,我想知道是否有人知道另一种修复方法。必须有一种类似于 Snapchat 或 WhatsApp 正在做的方式,因为当你写一条消息并在按下发送后立即终止应用程序时,消息将被传递。

我能想到的唯一方法是通过后台获取来完成,但我认为这不是最好的解决方案,因为我只想在应用程序发送到后台时建立一个连接.

我同意 Andy 的观点,你应该追求 NSURLSession 和背景 NSURLSessionConfiguration。请参阅 App Programming Guide for iOS: Background Execution 背景部分中的下载内容。

顺便说一句,您问题中的想法会很好地工作(特别是如果您需要支持 7.0 之前的 iOS 版本,其中 NSURLSession 及其后台会话不可用)。关于您的代码片段的两个观察结果:

  1. 按照您的编写方式,当您的 AnObject 超出范围时,您的 AnObject 会被提前释放,因此您的应用程序在尝试调用委托时会失败方法。确保保持对 AnObject.

  2. 的强引用
  3. 下载完成后别忘了调用endBackgroundTask。同样(更巧妙地),超时处理程序也应该结束后台任务。请参阅上述 App Programming Guide 执行有限长度任务 部分。

顺便说一下,您提到应用终止后请求继续。如果用户手动终止应用程序,则会同时终止您问题中考虑的后台任务以及后台 NSURLSession 任务。这些旨在在应用程序离开前台时优雅地处理继续任务,而不是在用户手动终止应用程序时。 NSURLSession 方法优雅地处理由于内存压力导致的终止,但不是手动终止。