1.需求
最近在做第三方支付,有一个倒计时15分钟的需求,用户进入后台在进入前台时,倒计时要正常运行。
2.实现
尝试阶段:
1.NSTimer正常情况在APP进入后台时下会立刻停止运行。
2.要让APP在后台无限运行有以下几种方式
a. 播放音频:应用程序可以在后台持续的播音或者录音。
b. 接收位置更新:随着设备位置的变化应用程序要持续获得地理位置更新。
c. 正在下载杂志:杂志类应用特例,应用程序能够在后台下载
d. 提供voip服务:应用程序能够在后台执行任意的代码,当然苹果会限制它的用途,你的应用必须提供voip服务。
而我们需要申请相应的权限,申请了权限如果提交appstore审核时找不到对应权限的入口(没有实现相应功能),就会被退回。
3.后台短时间运行。beginBackgroundTaskWithExpirationHandler。使用这个函数可以让我们在进入后台后,继续执行较短时间(模拟器测试为180s以内)。我们现在用这个函数来实现我们想要的效果。
3.代码
1.在相应的VC里注册通知,检测前后台
2.在进入后台时注册任务,进入前台时结束相应的任务
3.在需要的时候启动定时器,在需求实现时关闭相应的后台任务
4.运行结果
目前这种方式是可以实现我们的需求的。后台在任务执行完之前会一直运行定时器,结束后也会清除后台任务,没有内存溢出等问题。
5.问题
1.beginBackgroundTaskWithExpirationHandler与endBackgroundTask往往成对出现,相关资料中常有以下写法:
意思是在系统默认给的时间结束后,如果不结束任务,系统会杀掉APP。以上代码测试结果为不会杀掉APP。而且这种方式持续的时间大概180s,不能满足我的需求。
2.如果采用上一条的写法,是不是可以用递归的方式,杀掉任务后重新开一个任务呢?没有测试。
3.关于self.task系统返回的结果是一个随机数,而UIBackgroundTaskInvalid的值为0。
4.这种方式占用后台,会不会被拒。。没有测试。后会补充。
朋友提供一种方法似乎也可以,且不用占用后台,留待确认:
定义全局剩余时间变量timecount、进入后台注销timer,记录时间戳backinterval,进入前台记录时间戳foreinterval,重新开启timer,timecount = timecount-(foreinterval-backinterval)。