由于产品需求需要APP退回到后台后,还要存活,不能被挂起杀掉。虽然这个实在有违苹果的设计宗旨,而且耗电。(难道苹果电池不耐用都是因为这样的需求太多。哈哈~所以手闲的时候还是有必要直接都杀死应用啊)
扯远了,回到主题:接到这个需求,在网上查了下资料。
要想在后台常驻,无非就是以上这几种模式。在正常情况下我们可以调用
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]
来申请存活180s;
1.audio,即网上说的最多的后台播放无声音乐
直接上代码
1.在info.plist添加Required background modes
,添加App plays audio or streams audio/video using AirPlay
。或者直接在上图展示的位置打钩。
2。
@interface AppDelegate ()<CLLocationManagerDelegate>
@property(nonatomic, assign) BOOL shouldStopBg;
@property(nonatomic, strong) AVAudioPlayer *audioPlayer;
@end
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIBackgroundTaskIdentifier bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
_shouldStopBg = NO;
dispatch_async(dispatch_get_global_queue(0, 0), ^(){
while ( TRUE ) {
if ( _shouldStopBg ){ break; }
float remainTime = [application backgroundTimeRemaining];
NSLog(@"###!!!BackgroundTimeRemaining: %f",remainTime);
if ( remainTime < 20.0 ){
//在20s的时候播放音乐
NSLog(@"start play audio!");
NSError *audioSessionError = nil;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
if ( [audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&(audioSessionError)] )
{
NSLog(@"set audio session success!");
}else{
NSLog(@"set audio session fail!");
}
NSURL *musicUrl = [[NSURL alloc]initFileURLWithPath:[[NSBundle mainBundle] pathForResource:@"song" ofType:@"mp3"]];
self.audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:musicUrl error:nil];
self.audioPlayer.numberOfLoops = 0;
self.audioPlayer.volume = 0;
[self.audioPlayer play];
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
}
[NSThread sleepForTimeInterval:1.0];
}
});
}
2.Location updates 后台位置刷新
1.在上图Location updates 打钩
2.在info.plist增加Privacy - Location Always Usage Description
2.上代码,(这个假如你的应用没有用到位置的话,这个弹框会挺尴尬,而且在后台,屏幕状态栏有位置小图标,当然肯定耗电咯)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
[_locationManager requestAlwaysAuthorization];
if (@available(iOS 9.0, *)) {
_locationManager.allowsBackgroundLocationUpdates = YES;
} else {
// Fallback on earlier versions
}
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[_locationManager startUpdatingLocation];
}
以上方案在iOS10上可以,iOS11的话就有问题了
iOS11中info.plist必须添加Privacy - Location Always Usage Description
,Privacy - Location Always and When In Use Usage Description
,Privacy - Location When In Use Usage Description
,才可以有弹框,苹果优化的更细致了。同时在iPhone X上运行,退到后台你会发现状态栏有时间显示背景变为深蓝,点击则跳回应用内。所以说iPhone X这个后台刷新定位不行哈,太明显了!!!
简单的来说:就是iOS 要更新新的Key,
苹果现在增加了一项新的隐私保护功能 NSLocationAlwaysAndWhenInUseUsageDeion,
并且原有的NSLocationAlwaysUsageDeion 被降级为NSLocationWhenInUseUsageDeion。
所以应用程序的Info.plist必须包含NSLocationAlwaysAndWhenInUseUsageDescription和NSLocationWhenInUseUsageDescription
Snip20171113_39.png
所以风险大,就交给产品他们自己定夺喽~
3.其他后台任务
Background fetch,Remote notification, Background Transfer Service等感觉对实时刷新的都不够好,所以没去深究了~
推荐这篇,对上面几个名词解释蛮好的;
网友评论