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"
}