backgroundFetch,
是指,系统不管你APP是未启动的还是在后台的,还是挂起的。 都会以一定的时间执行performFetchWithCompletionHandler 。 可以执行30秒的任务。
与NSURLSession的backgroundSessionConfigurationWithIdentifier
是不同的东西。
backgroundSession,
NSURLSession 的backgroundSession 无需后台模式的开关 ,就支持在后台持续下载数据的。
handleEventsForBackgroundURLSession
_handleNonLaunchSpecificActions:forScene:withTransitionContext:completion:
下载完成后。唤醒app
顺序如下:
handleEventsForBackgroundURLSession-> NSURLSession的didFinishDownloadingToURL
->didCompleteWithError ->URLSessionDidFinishEventsForBackgroundURLSession
-(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler {
NSLog(@" 😊 %s %@ ",__func__, identifier);
[LocalNotficationHelper sendLocationNotfication:@"backgroundSession~~" description:@"下载完成"];
///只要调用completionHandler ,立即又会进入挂起了;
//但是挂起前,不会影响 urlSession的didfinishdownloading和didcompletWithError。但是会影响urlsessionManagerTaskDelegate中的 中的dispatch_group_async的回调。
// completionHandler();
[backgroundFetchManager addFinishEventsForBackgroundSesssionId:identifier block:completionHandler];
}
backgroundFetchManager.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface backgroundFetchManager : NSObject
+(void)addFinishEventsForBackgroundSesssionId:(NSString *)backgroundSessionIdentifier block: ( void (^)(void))completionBlock ;
+(void)backgroundfetchNewDataForUrl:(NSURL *)url callBackCompletion:(void (^)(UIBackgroundFetchResult result))completionBlock;
@end
backgroundFetchManager.m
#import <AFNetworking.h>
#import "backgroundFetchManager.h"
#import "LocalNotficationHelper.h"
@implementation backgroundFetchManager
+(NSMutableDictionary *)handleEventsForBackgroundURLSessionBlockDict {
static NSMutableDictionary * handleEventsForBackgroundURLSessionBlockDict;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
handleEventsForBackgroundURLSessionBlockDict =@{}.mutableCopy;
});
return handleEventsForBackgroundURLSessionBlockDict;
}
+(void)addFinishEventsForBackgroundSesssionId:(NSString *)backgroundSessionIdentifier block: ( void (^)(void))completionBlock {
if (backgroundSessionIdentifier &&completionBlock ) {
[[backgroundFetchManager handleEventsForBackgroundURLSessionBlockDict ] setObject:completionBlock forKey:backgroundSessionIdentifier];
}
}
+(void)backgroundfetchNewDataForUrl:(NSURL *)url callBackCompletion:(void (^)(UIBackgroundFetchResult result))completionBlock {
NSString*timeString= [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterFullStyle timeStyle:NSDateFormatterFullStyle];
NSString*file =[[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent: timeString];
NSURLSessionConfiguration *configuration= [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"12345"];
AFURLSessionManager*mananger= [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
__weak typeof(mananger) weakMananger= mananger;
[mananger setDidFinishEventsForBackgroundURLSessionBlock:^(NSURLSession * _Nonnull session) {
if (session.configuration.identifier) {
void (^completionBlock)(void) = [[backgroundFetchManager handleEventsForBackgroundURLSessionBlockDict] objectForKey: session.configuration.identifier ];
if (completionBlock) {
[[backgroundFetchManager handleEventsForBackgroundURLSessionBlockDict] removeObjectForKey:session.configuration.identifier];
}
completionBlock();
[weakMananger invalidateSessionCancelingTasks:YES];
}
}];
NSURLSessionDownloadTask*task= [mananger downloadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://down10.zol.com.cn/audio/AudioConverter_Demo.rar"]] progress:^(NSProgress * _Nonnull downloadProgress) {
NSLog(@" 😊 %s : %@",__func__, @(downloadProgress.fractionCompleted));
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSLog(@" 😊 %s :%@",__func__, file);
return [NSURL fileURLWithPath:file];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
if (filePath&&!error) {
NSLog(@"😊 下载成功: %s %@",__func__, filePath);
[LocalNotficationHelper sendLocationNotfication:@"backgroundSession~" description:[NSString stringWithFormat:@" 下载成功: 😊 %s %@",__func__, filePath]];
completionBlock(UIBackgroundFetchResultNoData);
} else {
NSLog(@"😊 下载失败 %s %@",__func__, error);
[LocalNotficationHelper sendLocationNotfication:@"backgroundSession~" description:[NSString stringWithFormat:@"下载失败 😊 %s %@",__func__, error]];
completionBlock(UIBackgroundFetchResultFailed);
}
[mananger invalidateSessionCancelingTasks:YES];
}];
[task resume];
}
@end
remote notfication fetch
aps消息体传输增加content-available字段为1,则是以静默推送的方法是进行的。
系统不管你APP是未启动的还是在后台的,还是挂起的。
都会唤醒app
application:didReceiveRemoteNotification:fetchCompletionHandler:
{
"aps": {
"content-available": 1
},
"userinfokey1":"asdfasdfasdf"
}