How do I get a background location update every n minutes in my iOS application?
I found a solution to implement this with the help of the Apple Developer Forums:
- Specify
location background mode
- Create an
NSTimer
in the background withUIApplication:beginBackgroundTaskWithExpirationHandler:
- When
n
is smaller thanUIApplication:backgroundTimeRemaining
it will work just fine. Whenn
is larger, thelocation manager
should be enabled (and disabled) again before there is no time remaining to avoid the background task being killed.
This works because location is one of the three allowed types of background execution.
Note: I lost some time by testing this in the simulator where it doesn't work. However, it works fine on my phone.
Send the location to the server every n minutes in the background in swift
In DidBackground:
- stop normalTimer.
- start New backgroundTaskTimer
In WillForeground:
- stop backgroundTaskTimer.
- start normalTimer
Find below sample code:
In Appdelegate:
Declaration:
var backgroundUpdateTask: UIBackgroundTaskIdentifier!
var backgroundTaskTimer:Timer! = Timer()
Implementation:
func doBackgroundTask() {
DispatchQueue.global(qos: .default).async {
self.beginBackgroundTask()
if self.backgroundTaskTimer != nil {
self.backgroundTaskTimer.invalidate()
self.backgroundTaskTimer = nil
}
//Making the app to run in background forever by calling the API
self.backgroundTaskTimer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(self.startTracking), userInfo: nil, repeats: true)
RunLoop.current.add(self.backgroundTaskTimer, forMode: RunLoopMode.defaultRunLoopMode)
RunLoop.current.run()
// End the background task.
self.endBackgroundTask()
}
}
func beginBackgroundTask() {
self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(withName: "Track trip", expirationHandler: {
self.endBackgroundTask()
})
}
func endBackgroundTask() {
UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
self.backgroundUpdateTask = UIBackgroundTaskInvalid
}
In ApplicationDidEnterBackground:
func applicationDidEnterBackground(_ application: UIApplication) {
//Start the background fetch
self.doBackgroundTask()
}
In ApplicationWillEnterForeground:
func applicationWillEnterForeground(_ application: UIApplication) {
if self.backgroundTaskTimer != nil {
self.backgroundTaskTimer.invalidate()
self.backgroundTaskTimer = nil
}
}
Getting user location every n minutes after app goes to background
After some days trying all possible solutions I was finally able to make it work. Here is what was wrong in my solution:
- I need to setup 2 UIBackgroundTaskIdentifiers, one for the timer, and another one for the locationManager
On my solution, just add:
UIApplication *app = [UIApplication sharedApplication];
bgTask2 = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask2];
bgTask2 = UIBackgroundTaskInvalid; }];
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
Get background location updates every 5 minutes
You should read the section Implementing Long-Running Background Tasks of in here.
And then pursue either register for significant location changes or declare itself as needing continuous background location updates.
Furthermore a solution to this problem was given here by wjans.
And I quote:
Found a solution to implement this with the help of the Apple
Developer Forums. I did the following:
•Specify location background
mode
•Use an NSTimer in the background by using
UIApplication:beginBackgroundTaskWithExpirationHandler:
•In case n is
smaller than UIApplication:backgroundTimeRemaining it does works just
fine, in case n is larger, the location manager should be enabled (and
disabled) again before there is no time remaining to avoid the
background task being killed. This does work since location is one of
the three allowed types of background execution.
Good luck :)
Related Topics
Presenting Modal in iOS 13 Fullscreen
How to Take a Screenshot Programmatically on Ios
How to Find Topmost View Controller on Ios
How to Create a Basic Uibutton Programmatically
Move View With Keyboard Using Swift
How to Use Background Thread in Swift
Convert HTML to Plain Text in Swift
How to Validate an Url on the Iphone
How to Convert Uiview to Pdf Within Ios
Best Practices For Storyboard Login Screen, Handling Clearing of Data Upon Logout
Performselector May Cause a Leak Because Its Selector Is Unknown
Swift: Extra Argument 'Error' in Call
How to Set the Cookies to Be Used by a Wkwebview
Making a Uitableview Scroll When Text Field Is Selected