/// AdTransmissionManager.m
//获取sessionManager
- (AFHTTPSessionManager*)sessionManager
{
if
(!_sessionManager) {
NSURLSessionConfiguration
*configuration = [
NSURLSessionConfiguration
backgroundSessionConfiguration:
self
.upload ? background_identifier_upload : background_identifier_download];
configuration.networkServiceType =
NSURLNetworkServiceTypeBackground
;
_sessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
_sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
//设置最大并发数1
_sessionManager.operationQueue.maxConcurrentOperationCount = 1;
__weak AdTransmissionManager* _weakSelf =
self
;
[_sessionManager setDidFinishEventsForBackgroundURLSessionBlock:^(
NSURLSession
*session) {
//此处的completionHandler在handleEventsForBackgroundURLSession中赋值
if
(_weakSelf.completionHandler) {
_weakSelf.completionHandler();
_weakSelf.completionHandler =
nil
;
}
}];
}
return
_sessionManager;
}
//用户切换到后台时,前台任务转为后台任务执行
- (
void
)enterBackground
{
//获取正在运行的前台任务
NSArray
* tasks = [
self
getRunningTasks];
self
.backgroundTasks = [
NSMutableArray
array];
for
(AdTransmissionOperation* task in tasks) {
//前台任务转为后台任务
AdBackgroundTransmissionOperation* backgroundTask = [[AdBackgroundTransmissionOperation alloc] initWithTask:task];
backgroundTask.sessionManager =
self
.sessionManager;
backgroundTask.delegate =
self
;
[
self
.backgroundTasks addObject:backgroundTask];
}
//进入后台
self
.InBackground =
YES
;
//启动第一个后台NSURLSessionTask
[
self
runBackground];
}
- (
void
)runBackground
{
if
(!
self
.InBackground) {
return
;
}
dispatch_queue_t dispatchQueue = _transmissionQueue;
if
(!dispatchQueue) {
return
;
}
dispatch_async(dispatchQueue, ^{
while (
self
.backgroundTasks.count != 0 &&
self
.InBackground) {
//文件分块传输,每一个文件后台传输任务都被分割成多个NSURLSessionTask
AdBackgroundTransmissionOperation* backgroundTask = [
self
.backgroundTasks firstObject];
//当AdBackgroundTransmissionOperation分块任务NSURLSessionTask传输失败或传输完成时,调用nextTask返回nil,此时需进入下一个AdBackgroundTransmissionOperation任务
NSURLSessionTask
* sessionTask = [backgroundTask nextTask];
if
(sessionTask) {
[sessionTask resume];
break
;
}
//移除当前AdBackgroundTransmissionOperation,进入下一个AdBackgroundTransmissionOperation
[
self
.backgroundTasks removeObjectAtIndex:0];
}
});
}
//用户进入app时调用,暂停后台任务,并将后台任务转为前台任务运行
- (
void
)enterForeground
{
self
.InBackground =
NO
;
[
self
.sessionManager.operationQueue cancelAllOperations];
dispatch_queue_t dispatchQueue = _transmissionQueue;
if
(!dispatchQueue) {
return
;
}
dispatch_async(dispatchQueue, ^{
AdBackgroundTransmissionOperation* backgroundTask = [
self
.backgroundTasks firstObject];
if
(backgroundTask.task.info.status == TSRunning) {
backgroundTask.task.info.status = TSSuspend;
}
});
...
}
/// AdBackgroundTransmissionOperation.m
// 获取下一个NSURLSessionTask,
- (
NSURLSessionTask
*)nextTask
{
NSURLSessionTask
* sessionTask =
nil
;
sessionTask = [
self
.sessionManager downloadTaskWithRequest:request progress:
nil
destination:^
NSURL
*(
NSURL
*targetPath,
NSURLResponse
*response) {
NSString
* path = ...;
return
[
NSURL
fileURLWithPath:path];
} completionHandler:^(
NSURLResponse
*response,
NSURL
*filePath,
NSError
*error) {
//do something
...
//在上一个NSURLSessionTask完成时继续后面的NSURLSessionTask
//call runBackground
}];
return
sessionTask;
}
/// AppDelegate.m
- (
void
)application:(UIApplication *)application handleEventsForBackgroundURLSession:(
NSString
*)identifier
completionHandler:(
void
(^)())completionHandler
{
NSLog
(@\\"handleEventsForBackgroundURLSession %@\\", identifier);
[AdTransmissionManager setCompletionHandler:completionHandler ForURLSession:identifier];
}