iOS后台模式BackgroundMode

概述

iOS平台提供给应用特殊的后台服务,应用在后台时仍被允许能执行一会。

后台模式

UIBackgroundModes Xcode Modes 
1. audio -> Audio.Airplay and Picture in Picture: 应用在后台时可以播放声音信息 应用场景:需要在后台播放音频 
2. location -> Location updates: 应用提供位置信息 应用场景:在后台时需要不断通知用户位置更新信息 
3. voip -> Voice over IP: 提供Voice-over-IP服务。 如skype网络电话 
4. fetch -> Background fetch: 应用场景:需不断地频繁的基于一定规律从网络上获取新的数据 supported in iOS 7.0 
5. remote-notification 应用场景:通过远程推送作为一个信号表明有新的数据需要下载,以尽可能减少用户直接点开通知后查看内容的等待时间 supported in iOS7.0 
6. newsstand-content 在后台时使用Newsstand框架(杂志)进行数据的下载更新 supported in iOS5.0 and later 
7. external-accessory 有规律的从固件获取信息,可以在后台不断的与外设进行沟通 supported in iOS 5.0 and later 
一些外设控制App,比如一些控制第三方MFi配件的应用,开启后可让应用不断的与外设进行沟通 
8. bluetooth-central -> Uses Bluetooth LE accessories 需要在后台不断更新蓝牙状态 CoreBluetooth supported in iOS 5.0 and later 
9. bluetooth-peripheral -> Acts as a Bluetooth LE accessory 需要在后台不断访问其他蓝牙设备获取数据 supported in iOS 6.0 and later 
这里写图片描述

后台执行场景

官方为我们界定了 3 类后台执行任务的场景:

  • Background Tasks:APP 在前台时启动某项任务,然后在未结束之前突然 切换到了后台,那么 APP 可以在切换回调里使用某些 API 来继续向系统请求一些时间来继续完成这个任务;完成之后通知系统,之后系统会将 APP 挂起;
  • Downloading:在后台启动从网络下载文件的任务 – 对于文件下载,iOS 有专门的机制;
  • Specific Backgournd Tasks:应用需要在后台一直执行代码;

Background Tasks

使用 API beginBackgroundTaskWithExpirationHandler来指定.执行过程中 APP 被切换到后台时,任务还没有完成,这个时间又会自动调整为一个时间片段(具体多少我没找到文档说明,都是说可以通过backgroundTimeRemaining 属性得到)。对于一个固定 task ,每次调用beginBackgroundTaskWithExpirationHandler,都会产生一个 token 值(UIBackgroundTaskIdentifier 实际是个整型),必须在任务执行结束时,调用 endBackgroundTask 并传递这个 token,来结束后台任务。另外,作为最佳实践,都应该传递一个 超时 handler,以防申请到的时间片段内,还是没能完成任务的话,做最后的清理和标注工作!如果不传的话,那么结果就是 iOS 直接 kill 掉你的APP 
doc and code from : iOS 后台任务设计指导

// 在某处定义一个 token 变量
UIBackgroundTaskIdentifier _bgTaskToken;

// 进入后台 委派方法回调
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    _bgTaskToken = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
        // 时间到了,任务还没完成,只能清理
        ...
        // 取消后台任务
        [application endBackgroundTask:_bgTaskToken];
        _bgTaskToken = UIBackgroundTaskInvalid;
    }];


    // 异步启动任务,这样不会阻塞 本委派方法回调
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 巴拉巴拉,做自己的任务
        ...

        // 任务在时间限制内结束啦,取消后台任务
        [application endBackgroundTask:_bgTaskToken];
        _bgTaskToken = UIBackgroundTaskInvalid;
    });
}

Apple Doc

Tracking the User’s Location

有三种方式来实现 位置的访问:

  • The significant-change location service(这也是官方推荐的方式)
  • Foreground-only location services
  • Background location services

The significant-change location service ,字面理解,就是只有位置有变化时才会发出通知,有人说这个时机是依据基站,切换了基站时,就会发出一次通知,所以频率会受基站的密度影响,所以市区更新频率会比郊区高。但好处 是这个服务不管你的 APP 是在前台还是后台,不管是否已经被挂起,或已经死掉了,他都会唤醒你的进程进行相应处理,所以应该是最省电的

Communicating with an External Accessory

外设设备有很多,比如一些心率监控器,会在必要的时候向手机推送数据。系统替 APP 监视这个连接,但有数据过来时,会唤醒 APP 进行处理,每次唤醒 APP 只有 10 S进行数据处理,如果10S不够,需要使用 beginBackgroundTaskWithExpirationHandler: 方法再申请一段时间进行处理;

【Note】:Apple 要求此类应用 需要提供一个 开启 和 关闭 连接的界面供用户使用;

Using Push Notifications to Initiate a Download

服务端推送的通知内容里加入 键值对 content-available = 1 ,那么 手机收到这个通知后,会自动启动 APP 到后台,或 唤醒(依旧保持后台执行),并回调 委托方法application:didReceiveRemoteNotification:fetchCompletionHandler:

Reference

App Programming Guide for iOS - Background Execution 
iOS 后台任务设计指导

posted @ 2018-04-02 16:28  心泪无恒  阅读(10535)  评论(0编辑  收藏  举报