美文网首页codeER.tec
关于iOS APP后台无限存活问题

关于iOS APP后台无限存活问题

作者: 达摩君 | 来源:发表于2017-11-13 18:26 被阅读169次

由于产品需求需要APP退回到后台后,还要存活,不能被挂起杀掉。虽然这个实在有违苹果的设计宗旨,而且耗电。(难道苹果电池不耐用都是因为这样的需求太多。哈哈~所以手闲的时候还是有必要直接都杀死应用啊)
扯远了,回到主题:接到这个需求,在网上查了下资料。

1.png
要想在后台常驻,无非就是以上这几种模式。在正常情况下我们可以调用[[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等感觉对实时刷新的都不够好,所以没去深究了~
推荐这篇,对上面几个名词解释蛮好的;

相关文章

网友评论

    本文标题:关于iOS APP后台无限存活问题

    本文链接:https://www.haomeiwen.com/subject/bkvzmxtx.html