后台传输在 iOS 中是如何工作的?

How does background transfer actually work in iOS?

我一直在使用 NSURLSession 在后台上传到 AWS S3。像这样:

NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@“some.identifier"];
NSURLSession* session = [NSURLSession sessionWithConfiguration:configuration delegate:someDelegate delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionUploadTask* task = [session uploadTaskWithRequest:request fromFile:[NSURL fileURLWithPath:httpBody]];
[task resume];

someDelegate中,我实现了didSendBodyDatadidCompleteWithErrorhandleEventsForBackgroundURLSession

我有三个问题:

  1. 我注意到如果我在上传过程中关闭应用程序,传输将继续并成功完成。 handleEventsForBackgroundURLSession 是否在应用程序关闭时传输完成时调用?
  2. 假设第一个问题的答案是肯定的,那么如何删除handleEventsForBackgroundURLSession中的httpBody呢?这是一个临时文件,传输完成后就不再需要了。
  3. 如果有人详细解释后台传输在 iOS 中的工作原理,我将不胜感激。即创建内存时,在哪些状态下调用哪些回调以及传输完成后如何唤醒应用程序。谢谢。

当调用应用委托的 handleEventsForBackgroundURLSession 时,您应该:


一些补充说明:

  • 对于应用程序终止时发生的情况似乎有些困惑。

    如果应用程序在其正常生命周期过程中终止,URLSession 守护程序将继续后台请求,完成您的上传,然后在完成后唤醒您的应用程序。

    但是手动强制退出应用程序(例如,双击主页按钮,向上滑动应用程序以强制其退出)是完全不同的事情(实际上,用户在说 "stop this app and everything associated with it") .这将停止后台会话。所以,是的,后台会话将在应用程序终止后继续,但是,不,如果用户强制退出应用程序则不会。

  • 你在Xcode中谈到了设置断点和观察这个。您应该知道附加到 Xcode 的过程会干扰正常的应用程序生命周期(它将 运行 保留在后台,防止它被挂起,或者在正常的事件过程中,终止)。

    但是在测试后台会话相关代码时,在您的应用程序终止时测试 handleEventsForBackgroundURLSession 工作流程至关重要,因此为此,我建议在测试时不要使用 Xcode 调试器这个维度的后台会话。

    我使用新的 OSLog 统一日志系统,因为 macOS 控制台可以查看应用程序记录的内容,而根本没有 Xcode 运行。然后我可以编写代码来开始一些下载或上传,终止应用程序,然后观察我插入的日志语句,以便通过 macOS 控制台在后台观察应用程序的重启。有关如何从 macOS 控制台查看 iOS 日志的教程,请参阅 Unified Logging and Activity Tracing 视频。