iOS中App进入后台,定时器继续执行
2017-12-06 本文已影响828人
lanmoyingsheng
需求:点击发送验证码并切换到后台,验证码不停止倒计时。
一、直接法
Apple只允许三种情况下App在后台一直执行,音频视频、定位、未知(还有一种没查到),如果是直播、视频播放、地图类的应用可以这样做,但是有些小需求则无需这样。
二、障眼法
{
int _countdownTimer; //倒计时
}
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) NSTimeInterval timestamp;
- (void)viewDidLoad {
[super viewDidLoad];
[self observeApplicationActionNotification];
}
- (void)getCodeBtnClick
{
xxxxxxxxxxxxx
if (获取验证码成功) {
getVerificationCodeBtn.enabled = NO;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:YES];
}
}
- (void)timerFireMethod:(NSTimer *)timer
{
NSString *remindWords = [NSString stringWithFormat:@"重新发送(%ds)", _countdownTimer--];
[_activatorView.getVerificationCodeBtn setTitle:remindWords forState:UIControlStateNormal];
[_activatorView.getVerificationCodeBtn setTitle:remindWords forState:UIControlStateDisabled];
if (_countdownTimer <= 0) {
[_activatorView.getVerificationCodeBtn setTitleColor:[TKUIHelper colorWithHexString:@"4359aa"] forState:UIControlStateNormal];
[timer invalidate];
timer = nil;
_countdownTimer = kCountdown;
[_activatorView.getVerificationCodeBtn setTitle:@"发送验证码" forState:UIControlStateNormal];
_activatorView.getVerificationCodeBtn.enabled = YES;
}
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)observeApplicationActionNotification {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground) name: UIApplicationDidEnterBackgroundNotification object:nil];
}
- (void)applicationDidEnterBackground {
_timestamp = [NSDate date].timeIntervalSince1970;
_timer.fireDate = [NSDate distantFuture];
}
- (void)applicationDidBecomeActive {
NSTimeInterval timeInterval = [NSDate date].timeIntervalSince1970-_timestamp;
_timestamp = 0;
NSTimeInterval ret = _countdownTimer-timeInterval;
if (ret>0) {
_countdownTimer = ret;
_timer.fireDate = [NSDate date];
} else {
_countdownTimer = 0;
_timer.fireDate = [NSDate date];
[self timerFireMethod:self.timer];
}
}
原理:监听进入后台、进入后台的消息,在进入后台时存时间戳,停掉定时器(系统会强制停止定时器);在进入前台时计算时间差。如果剩余时间大于时间差,则减去时间差,否则赋值剩余时间为0。这里为了体验更好,添加了停止和启动定时器的操作。
通过上面的代码,可以在App进入前、后台时做一些计算和定时器操作,完成定时器在后台执行的效果。