How to Get a Background Location Update Every N Minutes in My iOS Application

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 with UIApplication:beginBackgroundTaskWithExpirationHandler:
  • When n is smaller than UIApplication:backgroundTimeRemaining it will work just fine. When 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 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:

  1. stop normalTimer.
  2. start New backgroundTaskTimer

In WillForeground:

  1. stop backgroundTaskTimer.
  2. 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



Leave a reply



Submit