iOS development: solve the problem that the countdown (timer) cannot count normally when the App enters the background

preface

In the iOS development process, especially the demand for sending SMS verification code is a very common demand, which involves the use of countdown. However, if the countdown operation is in progress and the app runs in the background, what effect will the countdown have? So let's learn about this blog post.

Project requirements:

After clicking the operation, the countdown starts, and then the App runs in the background. The countdown does not stop and continues. SMS verification code and time countdown are applicable to this requirement.

Common sense:

iOS programs run in the background and will be "killed" by the system within 10 minutes, so the countdown will stop.

Solution:

Method 1: perform time difference operation according to the start time of recording and the current time. Monitor the messages entering the foreground and background, save the time stamp when entering the background, and stop the timer (the system will forcibly stop the timer); When entering the front desk again, calculate the time difference. If the remaining time is greater than the time difference, the time difference is subtracted, otherwise the remaining time is assigned as 0. (mainstream)

Method 2: apple only allows apps in three cases to be executed in the background: audio and video, location update and download. If they are live broadcast, video playback, maps and downloaded applications, they can be used in this way, but they don't need to be used for some small needs.

Method 3: complete a Task in the background by applying to Apple's system.

resolvent:

Show the application through a countdown example. Use method 1 for demonstration. Method 2 and method 3 will not be introduced in this chapter. If necessary, understand and solve it by yourself. The specific core code steps are as follows:

@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) int seconds;   // count down
@property (nonatomic, assign) NSTimeInterval timeStamp;
- (void)viewDidLoad {
    [super viewDidLoad];
    [self observeApplicationActionNotification];
}
#pragma mark -- button click event--
- (void)brewBtnClick {
 if (_timer) {
 return;
    }
 // Assign a value to the timer
    _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; //Perform time difference calculation
    _timestamp = 0;
    NSTimeInterval ret = _seconds - timeInterval;
 if (ret > 0) {
        _seconds = ret;
        _timer.fireDate = [NSDate date];
    } else {
        _seconds = 0;
        _timer.fireDate = [NSDate date];
        [self timerAction];
    }
}

Code illustration:

Through the above code, do some calculations and timer operations when the App enters the front and background to complete the effect that the timer is executed in the background and the countdown does not stop.

Posted on Mon, 29 Nov 2021 19:44:21 -0500 by srhino