前言

iOS有两种后台运行保活方式,第一种叫无声音乐保活(即在后台开启音频播放,只不过不需要播放出音量且不能影响其他音乐播发软件),第二种叫Background Task,但是这种方法在iOS 13以后只能申请短短的30秒钟时间,但是在iOS7-iOS13以前是可以申请到3分钟的保活时间的,当然我们也可以经过处理来申请到更多的保活时间。

无声音乐保活


(1)打开应用的Target页面Signing & Cabailities,添加Capability(Background Modes)勾选Audio,AirPlay,and Picture in Picture选项

(2)我们需要监听UIApplicationWillEnterForegroundNotification(应用进入前台通知)和UIApplicationDidEnterBackgroundNotification(应用进入后台通知)

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
- (void)appWillEnterForeground {}- (void)appDidEnterBackground {}

(3)编写音乐播放类
BackgroundPlayer.h

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>@interface BackgroundPlayer : NSObject <AVAudioPlayerDelegate>
{AVAudioPlayer* _player;
}
- (void)startPlayer;- (void)stopPlayer;
@end

BackgroundPlayer.m

#import "BackgroundPlayer.h"@implementation BackgroundPlayer- (void)startPlayer
{if (_player && [_player isPlaying]) {return;}AVAudioSession *session = [AVAudioSession sharedInstance];[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeDefault error:nil];NSString* route = [[[[[AVAudioSession sharedInstance] currentRoute] outputs] objectAtIndex:0] portType];if ([route isEqualToString:AVAudioSessionPortHeadphones] || [route isEqualToString:AVAudioSessionPortBluetoothA2DP] || [route isEqualToString:AVAudioSessionPortBluetoothLE] || [route isEqualToString:AVAudioSessionPortBluetoothHFP]) {if (@available(iOS 10.0, *)) {[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecordwithOptions:(AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP)error:nil];} else {// Fallback on earlier versions}}else{[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecordwithOptions:(AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDefaultToSpeaker)error:nil];}[session setActive:YES error:nil];NSURL *url = [[NSBundle bundleWithPath:WECAST_CLOUD_BUNDLE_PATH]URLForResource:@"你的音乐资源" withExtension:nil];_player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];[_player prepareToPlay];[_player setDelegate:self];_player.numberOfLoops = -1;BOOL ret = [_player play];if (!ret) {NSLog(@"play failed,please turn on audio background mode");}
}- (void)stopPlayer
{if (_player) {[_player stop];_player = nil;AVAudioSession *session = [AVAudioSession sharedInstance];[session setActive:NO error:nil];NSLog(@"stop in play background success");}
}@end

(4)在应用进入后台时开启保活

@property (nonatomic, strong) BackgroundPlayer* player;
- (void)appWillEnterForeground {if (self.player) {[self.player stopPlayBackgroundAlive];}
}- (void)appDidEnterBackground {if (_player == nil) {_player = [[BackgroundPlayer alloc] init];}[self.player startPlayer];
}

Background Task保活

(1)同样我们需要监听UIApplicationWillEnterForegroundNotification(应用进入前台通知)和UIApplicationDidEnterBackgroundNotification(应用进入后台通知)

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
- (void)appWillEnterForeground {}- (void)appDidEnterBackground {}

(2)使用Background Task申请保活时间,在应用进入后台时开启保活,在应用进入前台时关闭保活

@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundId;
- (void)appWillEnterForeground {[self stopKeepAlive];
}- (void)appDidEnterBackground {_backgroundId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{//申请的时间即将到时回调该方法NSLog(@"BackgroundTask time gone");[self stopKeepAlive];}];
}- (void)stopKeepAlive{if (_backgroundId) {[[UIApplication sharedApplication] endBackgroundTask:_backgroundId];_backgroundId = UIBackgroundTaskInvalid;}
}

(3)使用NSTimer循环申请保活时间,但是建议不要无限申请保活时间,因为系统如果发现该应用一直在后台运行时,是可能会直接crash掉你的应用的 ,错误码0x8badf00d

//开启定时器 不断向系统请求后台任务执行的时间
NSTimer *_timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(applyForMoreTime) userInfo:nil repeats:YES];
[_timer fire];//在这里我判断了申请次数,加上第一次申请保活时间的次数一共6次。
@property(nonatomic,assign) int applyTimes;
-(void)applyForMoreTime {if ([UIApplication sharedApplication].backgroundTimeRemaining < 10) {_applyTimes += 1;NSLog(@"Try to apply for more time:%d",_applyTimes);[[UIApplication sharedApplication] endBackgroundTask:_backIden];_backIden = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{[self stopKeepAlive];}];if(_applyTimes == 5){[_timer invalidate];_applyTimes = 0;[self stopKeepAlive];}}
}

iOS 后台运行保活相关推荐

  1. iOS 后台运行实现总结

    原文:http://www.jianshu.com/p/d3e279de2e32 iOS 后台运行的规则 应用的运行状态分为以下五种: Not running:应用还没有启动,或者应用正在运行但是途中 ...

  2. IOS后台运行 之 后台播放音乐

    IOS后台运行 之 后台播放音乐 iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像 ...

  3. IOS后台运行机制详解(二)

    (温馨提示:亲,请先看上篇,此文乃下篇) 三.iOS长时间后台运行的实现代码 1.检查设备是否支持多任务 Apple出于性能的考虑,并不是所有的iOS设备升级到iOS4以后都支持多任务,比如iPhon ...

  4. IOS后台运行机制详解(一)

    一.iOS的"伪后台"程序 首先,先了解一下iOS 中所谓的「后台进程」到底是怎么回事吧? Let me be as clear as I can be: the iOS mult ...

  5. IOS 后台运行 播放音乐

    iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...

  6. android 后台运行 保活

    文章不错,转载自:https://mp.weixin.qq.com/s/F7W66Y03BBTWOnsds1ZX3A 优雅保活方案,原来Android还可以这样保活! Android技术杂货铺 昨天 ...

  7. iOS后台运行机制1

    iOS支持三种后台运行方式: audio:在后台提供声音播放功能,包括音频流和播放视频时的声音 location:在后台可以保持用户的位置信息 voip:在后台使用VOIP功能 一.iOS的" ...

  8. iOS 后台运行一段时间(不是地图,音乐类型APP)

    iOS 通常是不能在后台运行的,尤其是用户点击锁屏键,APP进入后台,网络立马断开等.如何解决这个问题呢?在APP进入后台,APP怎么争取一些时间来"善后".代码如下:注:需要定义 ...

  9. iOS后台运行NSTimer

    iOS 允许的几种后台 几种后台存活的模式 ios7之后(一个app可以混合调用多种模式):Background Audio.VoIP.Location Services.Newsstand.Back ...

最新文章

  1. eclipse hibernate配置文件(*.hbm.xml)加上自动提示功能
  2. 数字图像处理实验(1):PROJECT 02-01, Image Printing Program Based on Halftoning
  3. MAUI安卓子系统调试方法(附安装教程)
  4. [已解决]Vistual Stdio 2015 installer Bootstrapper Packages 路径
  5. SpringBoot获取配置文件常量值
  6. 封装jquery的ajax,便于加载等待提示框
  7. 图论 —— 图的连通性 —— Tarjan 求强连通分量
  8. node js 技术架构_[视频] Node JS中的干净架构
  9. 社工大师_社工,与弱势者同行 | TED演讲
  10. python集合中的元素是否可以重复_python列表--查找集合中重复元素的个数
  11. 一个简单的BP神经网络matlab程序(附函数详解)
  12. Energetically Consistent Invertible Elasticity
  13. Python:***测试开源项目
  14. 企业微信API学习笔记
  15. html鼠标经过小手,css鼠标小手
  16. php 时间戳转换日期格式用法
  17. C语言要点系统复习三:scanf读取缓冲区的那些事
  18. 【简单封装】Android实现USB转232通讯
  19. windows7局域网网络共享文件夹和打印机的问题分析及解决
  20. 一条大蟒蛇和一条小毒蛇

热门文章

  1. 【BIOS 系列 2】编写驱动库模板
  2. 主板前置USB插线接法大全
  3. python的乘法实现方法
  4. 四旋翼飞行器8——APM飞控资料
  5. Vite 基本配置及原理
  6. Android中生成.xls的Excel文件
  7. 集美大学计算机网络试题2018,集美大学计算机网络基础选择题.doc
  8. i5 1035g1和r5 3500u哪个好
  9. 无法定位程序输入点 except_S120变频器的基本定位功能详解
  10. 西南民族大学计算机科学与工程学院官网,四川西南民族大学计算机科学与技术学院 软件工程转专业...