3大后台任务

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


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容