Since the iOS system is in "pseudo-background" running mode, when the HOME key is pressed, if the program does not do any operation, the application will have a 5-second execution buffering time, the random program is suspended, and all task terminals, including timer and position update operations, but after the program turns on the background mode switch, some tasks can be executed in the background, such as audio, positioning, Bluetooth, downloading, VOIP. Even so, the background operation of the program can be extended by up to 594 seconds (about 10 minutes). Unfortunately, the program is likely to be rejected when the app is launched after declaring the background mode. Based on this, I have developed a method to allow timers and positioning to continue running when the app enters the foreground without declaring the background mode.
The implementation principle is as follows:
Using iOS' notification mechanism, a notification is sent when the program enters the background and returns to the foreground again, and the current time entering the background and the current time returning to the foreground again, calculate the time interval between the two, add a notification listener wherever the program needs it, and execute a code block in the listening method. The parameters in the code block are the notification object and the calculated time interval. Taking the timer as an example, after the program enters the background, the timer stops running. At this time, use the above method to execute the contents of the code block when the program returns to the foreground again. When the program enters the background, the current time interval of the timer plus the time interval parameters of the code block can make the timer time accurately. Without further ado, please enter the code:
In the implementation file:
- (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. [[NSNotificationCenter defaultCenter]postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil]; } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. [[NSNotificationCenter defaultCenter]postNotificationName:UIApplicationWillEnterForegroundNotification object:nil]; }
Code description: After the program enters the background, use the system notification mechanism to notify the program to enter the background and return to the foreground again, and listen to the object as all objects.
Then define a class YTHandlerEnterBackground that handler enters the background
// // // Time-sharing rental// // Created by Ke Qishu on 17/2/24.// Copyright © 2017 Keqipu. All rights reserved.// #import <Foundation/> #import <UIKit/> /** Enter the background block typedef */ typedef void(^YTHandlerEnterBackgroundBlock)(NSNotification * _Nonnull note, NSTimeInterval stayBackgroundTime); /** Processing to enter the background and calculate the time interval class left in the background */ @interface YTHandlerEnterBackground : NSObject /** Add observer and handle background */ + (void)addObserverUsingBlock:(nullable YTHandlerEnterBackgroundBlock)block; /** Remove background observer */ + (void)removeNotificationObserver:(nullable id)observer; @end
In the implementation file:
// // // Time-sharing rental// // Created by Ke Qishu on 17/2/24.// Copyright © 2017 Keqipu. All rights reserved.// #import "" @implementation YTHandlerEnterBackground + (void)addObserverUsingBlock:(YTHandlerEnterBackgroundBlock)block { __block CFAbsoluteTime enterBackgroundTime; [[NSNotificationCenter defaultCenter]addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { if (![ isKindOfClass:[UIApplication class]]) { enterBackgroundTime = CFAbsoluteTimeGetCurrent(); } }]; __block CFAbsoluteTime enterForegroundTime; [[NSNotificationCenter defaultCenter]addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { if (![ isKindOfClass:[UIApplication class]]) { enterForegroundTime = CFAbsoluteTimeGetCurrent(); CFAbsoluteTime timeInterval = enterForegroundTime-enterBackgroundTime; block? block(note, timeInterval): nil; } }]; } + (void)removeNotificationObserver:(id)observer { if (!observer) { return; } [[NSNotificationCenter defaultCenter]removeObserver:observer name:UIApplicationDidEnterBackgroundNotification object:nil]; [[NSNotificationCenter defaultCenter]removeObserver:observer name:UIApplicationWillEnterForegroundNotification object:nil]; } @end
This class implements a method used to add notification listeners, handle background and remove notification listeners. It should be noted that in the addObserverUsingBlock method, there must be a judgment of if (![ isKindOfClass:[UIApplication class]]) , otherwise the code block in the addObserverForName method will be executed multiple times, and this code is executed twice. The addObserverUsingBlock method is to call the add notification listener in the viewWillAppear method, and call the remove notification listener in the viewWillDisappear method.
For example, in the NSTimer controller that uses the timer:
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [YTHandlerEnterBackground addObserverUsingBlock:^(NSNotification * _Nonnull note, NSTimeInterval stayBackgroundTime) { = -stayBackgroundTime; }]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [ invalidate]; [YTHandlerEnterBackground removeNotificationObserver:self]; }
I defined a timer object timer property that counts down 5 minutes, and defined a timer current countdown time interval rentTimerInterval property. In the code block of add notification listener, rentTimerInterval is equal to the countdown time interval when entering the background minus the time interval when the program stays in the background. When the timer returns to the foreground again, the time interval at this time is continuous. Although the timer does not continue to run in the background, using this method also achieves the correct real-time timer.
Similarly, when the program has a location update function, when the program enters the background, the location service object will automatically stop updating. At this time, the method is still to call the above two methods to enter the background, so that after the program enters the background, it starts positioning again:
In the class that requires location update:
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; = self; [ startUserLocationService]; //Enter the background and then enter the front desk to start positioning again [YTHandlerEnterBackground addObserverUsingBlock:^(NSNotification * _Nonnull note, NSTimeInterval stayBackgroundTime) { [ startUserLocationService]; }]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; //Stop positioning = nil; [ stopUserLocationService]; //Remove the background monitoring [YTHandlerEnterBackground removeNotificationObserver:self]; }
This is the Baidu Map SDK
Using this method, tasks that need to be run in the background such as timers and location updates can achieve corresponding requirements. But the trouble is that these two methods must be called in any required class. You can add other parameters when the program enters the background and returns to the foreground according to your needs (notifying the object parameters are necessary), such as saving the operations before entering the background, etc. Or define different ways to add notification listeners to achieve different needs.
The above is the solution to the timer and position update stopping problem introduced by the editor to you after the iOS application enters the background. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support for my website!