iOS后台运行程序

苹果默认三种类型程序可以在后台运行:音频播放类、location位置更新类、voip。

在开发中经常需要在程序进入后台之后仍正常运行,但是当app进入后台,其主线程都会被挂起,这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除。
那么如果想要继续在后台运行任务,可以通过- beginBackgroungTaskWithExpirationHandler:方法来请求后台执行时间;也可以利用音频类来达到我们的目的。

1.- beginBackgroungTaskWithExpirationHandler:
只要调用了- beginBackgroundTaskWithExpirationHandler: 此方法申请时间,程序就会允许app的线程继续执行,直到任务结束。The block argument called “handler” is what will happen when the background task expire (10min).
To get your code running you need to put your code out of the expiration handler:.
As Apple document quote : “You should not use this method simply to keep your app running after it moves to the background.”

例:

__weak __typeof(self)weakSelf = self;
   dispatch_async(dispatch_queue_create("bkthread", DISPATCH_QUEUE_CONCURRENT), ^{
        while (weakSelf.backgroundMode) {
            sleep(2);
            NSLog(@"I am still alive, haha...");
        };
    });

    UIApplication* app = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier bgTask;
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        dispatch_async(dispatch_get_main_queue(),^{
            if(bgTask != UIBackgroundTaskInvalid) {
                bgTask = UIBackgroundTaskInvalid;
                [app endBackgroundTask:bgTask];
            }
        });
    }];

注意:
1)- beginBackgroundTaskWithExpirationHandler:(handler)和 - endBackgroundTask这两个方法必须要成对出现。(As quote : “Each call to this method must be balanced by a matching call to the endBackgroundTask: method.” Or else this app will be killed.)
2)任务完成后的清理工作需要在handler中完成。

使用位置:
1)可以在APPDelegate中的applicationDidEnterBackground:中申请;

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];

在合适的地方添加委托。但是此时- applicationDidEnterBackground: 接受的参数并不是UIApplication类型,需注意。

2.音频播放
1)先在info.plist文件中加入key:Required background modes, value:audio / app plays audio
2)创建一个音频播放,循环播放

  NSError *error = nil;
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    if ([audioSession setCategory:AVAudioSessionCategoryPlayback error:&error]) {
        NSLog(@"successfully audio Session");
    } else {
        NSLog(@"could not set the audio Session");
    }

    NSString *path = [[NSBundle mainBundle] pathForResource:@"music" ofType:@"mp3"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    NSError *playerError = nil;
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithData:data error:&playerError];
    if (player) {
        player.delegate = self;
        [player setNumberOfLoops:-1];
        if ([player prepareToPlay] &&[player play]) {
            NSLog(@"player play success");
        } else {
            NSLog(@"player error");
        }
    }

3)将以上代码并发执行

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
        dispatch_async(dispatch_get_main_queue(),^{
//code
        });});

3.系统仍给预留的时间

 //[[UIApplication sharedApplication] backgroundTimeRemaining] 默认为DBL_MAX常量,这是double类型可表示的最大值
    NSTimeInterval backgroundTimeRemaining = [[UIApplication sharedApplication] backgroundTimeRemaining];
    if (backgroundTimeRemaining == DBL_MAX){
        NSLog(@"Background Time Remaining = Undetermined”);
    } else {
        NSLog(@"Background Time Remaining = %.02f Seconds", backgroundTimeRemaining);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值