如果正在iOS中使用NSURLSession,app会在下载完成时自动重启。AppDelegate中的方法application:handleEventsForBackgroundURLSession:completionHandler:负责创建适当地session,保存completionHandler(这是该方法的传递的,需要我们去手动保存它),并在session的代理方法URLSessionDidFinishEventsForBackgroundURLSession:去调用保存的completionHandler。下面的代码展示了一个创建和启动一个下载任务:
/// Objective-C
NSURL *url = [NSURL URLWithString:@"https://www.example.com/"];
NSURLSessionDownloadTask *backgroundDownloadTask = [backgroundSession downloadTaskWithURL:url];
[backgroundDownloadTask resume];
/// Swift
if let url = URL(string: "https://www.example.com/") {
let backgroundDownloadTask = backgroundSession.downloadTask(with: url)
backgroundDownloadTask.resume()
}
下面是iOS中后台下载的session代理方法:
/// Objective-C
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
AppDelegate *appDelegate = (AppDelegate *)[[[UIApplication sharedApplication] delegate];
if (appDelegate.backgroundSessionCompletionHandler) {
CompletionHandler completionHandler = appDelegate.backgroundSessionCompletionHandler;
appDelegate.backgroundSessionCompletionHandler = nil;
completionHandler();
}
NSLog(@"All tasks are finished");
}
/// Swift
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
guard let appDelegate = UIApplication.sharedApplication.delegate as? AppDelegate else {
return
}
if let completionHandler = appDelegate.backgroundSessionCompletionHandler {
appDelegate.backgroundSessionCompletionHandler = nil
completionHandler()
}
}
下面是AppDelegate中的代理方法:
/// Objective-C
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (copy) CompletionHandler backgroundSessionCompletionHandler;
@end
@implementation AppDelegate
- (void)application:(UIApplication *)application
handleEventsForBackgroundURLSession:(NSString *)identifier
completionHandler:(void (^)())completionHandler
{
self.backgroundSessionCompletionHandler = completionHandler;
}
@end
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var backgroundSessionCompletionHandler: CompletionHandler?
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
backgroundSessionCompletionHandler = completionHandler
}
}