在实际开发中会遇见下载比较大的视频时。不能在前台完成全部下载,需要在后台进行下载。
ios13以后正常后台申请的时间最多为31秒,31秒后就会进入休眠状态等待用户再次启动。
为了保证应用在后台长时间正常进行运行,目前是有2种方式
1.申请后台播放音乐功能
2.申请后台定位功能
目前主流的项目比如QQ等、都是使用无音乐播放来保证后台保活,我们项目也主要介绍该功能的实现ps:但是假如APP没有音乐播放功能,提交审核会被拒,慎用
xcode里面需要配置如下:该项目只需要勾选第一个就可以了
xcode配置.png
废话不多说直接上代码:
1.先拿到本地的静音文件
_queue = dispatch_queue_create("Mp3Play", NULL);
//静音文件
NSString*filePath = [[NSBundlemainBundle]pathForResource:@"mute"ofType:@"mp3"];
NSURL*fileURL = [[NSURLalloc]initFileURLWithPath:filePath];
self.playerBack = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[self.playerBackprepareToPlay];
// 0.0~1.0,默认为1.0
self.playerBack.volume=0.01;
// 循环播放
self.playerBack.numberOfLoops= -1;
2.启用2个定时器来,一个控制器是控制我们打印来确认确实保活、另外一个控制器是来监听我们后台是否需要重新去申请时间
启动定时器
dispatch_async(_queue, ^{
//启动2个定时器 中间使用了一个第三方的类来控制,保证不会造成引用循环、后期再优化成gcd的定时器
self.timerLog = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:1 target:self.wgProxy selector:@selector(log) userInfo:nil repeats:YES];
self.timerAD = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:_circulaDuration target:self.wgProxy selector:@selector(startAudioPlay) userInfo:nil repeats:YES];
_runloopRef = CFRunLoopGetCurrent();
[[NSRunLoop currentRunLoop] addTimer:self.timerAD forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer:self.timerLog forMode:NSDefaultRunLoopMode];
CFRunLoopRun();
});
3.在定时器将要销毁的时候再次去请求后台时间来保证我们可以一直保活
/**
申请后台
*/
- (void)applyforBackgroundTask{
self.task =[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] endBackgroundTask:self.task];
self.task = UIBackgroundTaskInvalid;
});
}];
}
献上具体源码地址:github地址
网友评论