實(shí)戰(zhàn)出真知 ,下面帶大家慢慢玩轉(zhuǎn)后臺存活。
首先新建個項(xiàng)目 ,寫上幾句簡單的代碼
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic , strong) dispatch_source_t timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
__block int flag = 0;
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 1 * NSEC_PER_SEC );
dispatch_source_set_event_handler(_timer, ^{
flag ++;
NSLog(@"flag = %d",flag);
});
dispatch_resume(_timer);
}
接下來 我們運(yùn)行項(xiàng)目,控制臺能循環(huán)打印信息 并且累加;這時候我們按下Home鍵,切到后臺,這時候控制臺的信息不打印了,這是為什么呢,timer失去作用了。
分析問題
一般來說,沒有進(jìn)行過任何設(shè)置的app,默認(rèn)退到后臺極短的幾秒后就變成掛起狀態(tài)
初步解決
利用 UIBackgroundTaskIdentifier 后臺任務(wù)標(biāo)記時,讓我們來看看后臺程序能撐多久
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self startBackgroundTask];
}
- (void)startBackgroundTask{
UIApplication* app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier bgTask ;
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
//這里延遲的系統(tǒng)時間結(jié)束
NSLog(@"%f",app.backgroundTimeRemaining);
}];
}
在appdelegate中加上上述代碼 ,運(yùn)行程序,再切換至后臺,接著我們再觀察控制臺的打印信息,看看什么時候停止打印。

image.png
我們可以看到 后臺在三分鐘左右的樣子 后臺任務(wù)結(jié)束,并且預(yù)留了4秒左右的緩沖時間。這時候app休眠了。
方法二次改進(jìn)
我們利用定位系統(tǒng)保持后臺永活
首先我們打開應(yīng)用位置更新功能

image.png
然后再plist文件中寫上
<key>NSLocationAlwaysUsageDescription</key>
<string>Location is required to find out where you are</string>
繼續(xù)加上如下代碼
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self startBackgroundTask];
[self startLocationUpdate];
}
- (void)startLocationUpdate{
if(!_locationManager){
_locationManager = [[CLLocationManager alloc] init];
_locationManager.allowsBackgroundLocationUpdates = YES;
_locationManager.delegate = self;
[_locationManager requestAlwaysAuthorization];
[_locationManager startUpdatingLocation];
}
}
接下來運(yùn)行再切換后臺
等待三分鐘看看結(jié)果
這時候發(fā)現(xiàn)后臺控制器一直處于打印狀態(tài) ,大功告成。
額外擴(kuò)展
我們也可以用后臺播放視頻的方法來做到后臺永活的功能,做法與后臺定位的方式類似,這里就不多說了
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self stratBadgeNumberCount];
[self startBgTask];
/** 播放聲音 */
[self.player play];
}
- (AVAudioPlayer *)player{
if (!_player){
NSURL *url=[[NSBundle mainBundle]URLForResource:@"work5.mp3" withExtension:nil];
_player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
[_player prepareToPlay];
//一直循環(huán)播放
_player.numberOfLoops = -1;
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
[session setActive:YES error:nil];
}
return _player;
}