Painted painted levels: fostered fostered fostered

Tags: “iOS verification code background countdown” “NSTimer background run” “iOS timer background run


SMS verification code login is very common in app. Compared with the login method of account and password, SMS verification code login not only saves users the tedious task of remembering passwords, but also reduces the risk of password disclosure to a large extent. However, the app operator will pay the corresponding SMS fee for each SMS message sent. Therefore, in order to prevent malicious frequent access, the interface for sending SMS verification codes will be designed with restriction logic. For example, for the same mobile phone number, the interface will not send the SMS verification code again within 120 seconds. In order to optimize the user experience, the app often makes the corresponding logic control: after clicking the “Get verification code” button, the button will be set to unclickable state and a 120-second countdown will start. After the countdown, the button will be restored to clickable state.

Implementing a countdown button based on the above requirements is not that difficult, just using NSTimer. But since NSTimer is suspended when the app is in the background, NSTimer won’t continue working until the app is in the foreground (if it hasn’t already been released), this will cause the countdown on the button to miss the time the app was in the background. So, developers need to find a way to make up that time.

How to make up this time is the content of this article. Before that, take a look at the countdown scene of SMS verification code in the following figure.

To make up for the time the app enters the background, there are two ideas:

    1. Record the time of app in the background, replenish timer after APP enters the foreground;
    1. Try to make app timer run for more than 120 seconds after the app enters the background.
Idea 1: Record how long the app is in the background

Through listening UIApplicationDidEnterBackgroundNotification and UIApplicationWillEnterForegroundNotification can access to the app into the background and return to front desk timestamp, The difference between these two timestamps is the time the app is in the background, and then the time is used to compensate for the time of the timer to achieve the requirements. The code is as follows:

#pragma mark - Notifications

- (void)applicationDidEnterBackground:(id)sender {
    NSLog(@"%s", __func__);
    
    _didEnterBackgroundTimestamp = [[NSDate date] timeIntervalSince1970];
}

- (void)applicationWillEnterForeground:(id)sender {
    NSLog(@"%s", __func__);
    
    NSTimeInterval willEnterForegroundTimestamp = [[NSDate date] timeIntervalSince1970];
    
    NSInteger onBackgroundSeconds = floor((_didEnterBackgroundTimestamp == 0)? 0: (willEnterForegroundTimestamp - _didEnterBackgroundTimestamp));
    _currentInteger -= onBackgroundSeconds;
}
Copy the code
  • didEnterBackgroundTimestampIs a global variable used to record the time stamp when the APP enters the background;
  • onBackgroundSecondsIndicates the time (seconds) of the app in the background. Use triadic operation to exclude the situation when APP starts directly;
  • The floor() function rounds down the Double to ensure that the countdown does not end prematurely.
Idea 2: Keep NSTimer running in the background

First, Apple will allow developers to apply to the system for permission to run apps such as Amap and Didi Chuxing using location services, and QQ Music and netease Cloud Music using audio services. However, if you apply for permission, you have to ensure that the app provides the appropriate services, or you will be rejected when you launch the App Store. Therefore, for simple countdown scenarios, this approach is not considered. Fortunately, iOS provides an API for developers to temporarily borrow background permissions to give apps up to 180 seconds of background permissions. When it comes to “borrowing”, there must be an “iOU” (voucher), and there must be borrowing and returning. In app into the background, through listening UIApplicationDidEnterBackgroundNotification, call the API to borrow 180 seconds in the background to the system permissions, and keep to borrow credentials. When the borrowing time is about to expire or after finishing what needs to be done, API is called to return background permission to the system, and the borrowing certificate is marked as invalid state. The specific code is as follows.

- (void)stopCountdown {
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
    
    [self endBackgroundTask];
    [self setEnabled:YES];
    
    [_timer invalidate];
    _timer = nil;
}


#pragma mark - Private functions

- (void)startBackgroundTask {
    
    __weak typeof(self) weakSelf = self;
    _backgroundTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [weakSelf endBackgroundTask];
    }];
}

- (void)endBackgroundTask {
    
    [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskId];
    _backgroundTaskId = UIBackgroundTaskInvalid;
}


#pragma mark - Notifications

- (void)applicationDidEnterBackground:(id)sender {
    NSLog(@"%s", __func__);
    
    [self startBackgroundTask];
}
Copy the code
  • backgroundTaskIdIs a global variable, which represents the credentials generated by borrowing background permissions from the system;
  • beginBackgroundTaskWithExpirationHandler Is a block that is triggered when the borrowed background permission is about to expire, in which to do the operation of “return permission”;
  • Is called after the timer countdown endsstopCountdown Method, in which the “restore permissions” operation is performed in advance.

These are the two ways the author uses to realize the countdown button of SMS verification code. In order to facilitate reuse, the author has encapsulated the countdown function into the button, and the engineering code can be obtained from QiCountdownButton.


Recommended articles:

IOS environment variable configuration iOS processing regular tasks commonly used methods algorithm small column: greedy algorithm iOS fast implementation of pagination interface to build iOS interface rotation strange dance weekly