后台传输在 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
中,我实现了didSendBodyData
、didCompleteWithError
和handleEventsForBackgroundURLSession
。
我有三个问题:
- 我注意到如果我在上传过程中关闭应用程序,传输将继续并成功完成。
handleEventsForBackgroundURLSession
是否在应用程序关闭时传输完成时调用?
- 假设第一个问题的答案是肯定的,那么如何删除
handleEventsForBackgroundURLSession
中的httpBody
呢?这是一个临时文件,传输完成后就不再需要了。
- 如果有人详细解释后台传输在 iOS 中的工作原理,我将不胜感激。即创建内存时,在哪些状态下调用哪些回调以及传输完成后如何唤醒应用程序。谢谢。
当调用应用委托的 handleEventsForBackgroundURLSession
时,您应该:
- 保存完成处理程序;
- 实例化你的背景
NSURLSession
;
- 让您的所有委托方法都被调用;
- 在您的
URLSession:task:didCompleteWithError:
中,您可以删除那些临时文件;和
- 在
URLSessionDidFinishEventsForBackgroundURLSession:
中,您可以调用保存的完成处理程序。
一些补充说明:
对于应用程序终止时发生的情况似乎有些困惑。
如果应用程序在其正常生命周期过程中终止,URLSession
守护程序将继续后台请求,完成您的上传,然后在完成后唤醒您的应用程序。
但是手动强制退出应用程序(例如,双击主页按钮,向上滑动应用程序以强制其退出)是完全不同的事情(实际上,用户在说 "stop this app and everything associated with it") .这将停止后台会话。所以,是的,后台会话将在应用程序终止后继续,但是,不,如果用户强制退出应用程序则不会。
你在Xcode中谈到了设置断点和观察这个。您应该知道附加到 Xcode 的过程会干扰正常的应用程序生命周期(它将 运行 保留在后台,防止它被挂起,或者在正常的事件过程中,终止)。
但是在测试后台会话相关代码时,在您的应用程序终止时测试 handleEventsForBackgroundURLSession
工作流程至关重要,因此为此,我建议在测试时不要使用 Xcode 调试器这个维度的后台会话。
我使用新的 OSLog 统一日志系统,因为 macOS 控制台可以查看应用程序记录的内容,而根本没有 Xcode 运行。然后我可以编写代码来开始一些下载或上传,终止应用程序,然后观察我插入的日志语句,以便通过 macOS 控制台在后台观察应用程序的重启。有关如何从 macOS 控制台查看 iOS 日志的教程,请参阅 Unified Logging and Activity Tracing 视频。
我一直在使用 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
中,我实现了didSendBodyData
、didCompleteWithError
和handleEventsForBackgroundURLSession
。
我有三个问题:
- 我注意到如果我在上传过程中关闭应用程序,传输将继续并成功完成。
handleEventsForBackgroundURLSession
是否在应用程序关闭时传输完成时调用? - 假设第一个问题的答案是肯定的,那么如何删除
handleEventsForBackgroundURLSession
中的httpBody
呢?这是一个临时文件,传输完成后就不再需要了。 - 如果有人详细解释后台传输在 iOS 中的工作原理,我将不胜感激。即创建内存时,在哪些状态下调用哪些回调以及传输完成后如何唤醒应用程序。谢谢。
当调用应用委托的 handleEventsForBackgroundURLSession
时,您应该:
- 保存完成处理程序;
- 实例化你的背景
NSURLSession
; - 让您的所有委托方法都被调用;
- 在您的
URLSession:task:didCompleteWithError:
中,您可以删除那些临时文件;和 - 在
URLSessionDidFinishEventsForBackgroundURLSession:
中,您可以调用保存的完成处理程序。
一些补充说明:
对于应用程序终止时发生的情况似乎有些困惑。
如果应用程序在其正常生命周期过程中终止,
URLSession
守护程序将继续后台请求,完成您的上传,然后在完成后唤醒您的应用程序。但是手动强制退出应用程序(例如,双击主页按钮,向上滑动应用程序以强制其退出)是完全不同的事情(实际上,用户在说 "stop this app and everything associated with it") .这将停止后台会话。所以,是的,后台会话将在应用程序终止后继续,但是,不,如果用户强制退出应用程序则不会。
你在Xcode中谈到了设置断点和观察这个。您应该知道附加到 Xcode 的过程会干扰正常的应用程序生命周期(它将 运行 保留在后台,防止它被挂起,或者在正常的事件过程中,终止)。
但是在测试后台会话相关代码时,在您的应用程序终止时测试
handleEventsForBackgroundURLSession
工作流程至关重要,因此为此,我建议在测试时不要使用 Xcode 调试器这个维度的后台会话。我使用新的 OSLog 统一日志系统,因为 macOS 控制台可以查看应用程序记录的内容,而根本没有 Xcode 运行。然后我可以编写代码来开始一些下载或上传,终止应用程序,然后观察我插入的日志语句,以便通过 macOS 控制台在后台观察应用程序的重启。有关如何从 macOS 控制台查看 iOS 日志的教程,请参阅 Unified Logging and Activity Tracing 视频。