写点什么

iOS 开发:解决 App 进入后台,倒计时(定时器)不能正常计时的问题

用户头像
三掌柜
关注
发布于: 3 小时前

项目需求:

点击操作之后倒计时开始,然后 App 在后台运行,倒计时不停止继续执行。短信验证码 、时间倒计时等情况都适用这个需求。

常理:

iOS 程序进入后台运行,10 分钟之内就会被系统“杀死”,所以倒计时会停止执行。

解决思路:

方法一:根据记录开始的时间和获取当前时间进行时间差操作进行处理。监听进入前台、进入后台的消息,在进入后台的时候存一下时间戳,停掉定时器(系统会强制停止定时器);在再进入前台时,计算时间差。若剩余的时间大于时间差,就减去时间差,否则赋值剩余时间为 0。(主流)


方法二:苹果只允许三种情况下的 App 在后台可以一直执行:音视频、定位更新、下载,若是直播、视频播放、地图类、有下载的应用可以这样使用,但是有些小需求就不需这样做。


方法三:通过向苹果的系统申请,在后台完成一个 Task 任务。

解决方法:

通过一个倒计时实例来展现一下运用,使用方法一来进行演示,方法二和方法三不再本篇进行介绍,如有需要自行了解解决。具体核心代码步骤如下所示:

@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) int seconds;   // 倒计时
@property (nonatomic, assign) NSTimeInterval timeStamp;
- (void)viewDidLoad {
    [super viewDidLoad];
    [self observeApplicationActionNotification];
}
#pragma mark --按钮点击事件--
- (void)brewBtnClick {
    if (_timer) {
        return;
    }
    // 给计时器赋值
    _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector: @selector(timerAction) userInfo:nilrepeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}
- (void)timerAction {
    self.seconds --;
    remainingTimeBtn.userInteractionEnabled = NO;
    if (self.seconds <= 0) {
        shapeLayer.strokeColor = [UIColor colorWithHexString:@"#77CAC6"].CGColor;
        [_timer invalidate];
        _timer = nil;
    }
}
- (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 = _seconds - timeInterval;
    if (ret > 0) {
        _seconds = ret;
        _timer.fireDate = [NSDate date];
    } else {
        _seconds = 0;
        _timer.fireDate = [NSDate date];
        [self timerAction];
    }
}
复制代码

代码图示:






最后:

通过以上的代码,在 App 进入前、后台时做一些计算和定时器操作,完成定时器在后台执行,倒计时不停止的效果。以上就是本章的全部内容,欢迎关注三掌柜的微信公众号“程序猿 by 三掌柜”,三掌柜的新浪微博“三掌柜 666”,欢迎关注!

发布于: 3 小时前阅读数: 6
用户头像

三掌柜

关注

某某某技术有限责任公司架构师 2021.02.05 加入

一分耕耘,不一定有一分收获,但十分耕耘,一定会有一分收获!

评论 (1 条评论)

发布
用户头像
8月日更第三天
3 小时前
回复
没有更多了
iOS开发:解决App进入后台,倒计时(定时器)不能正常计时的问题