We are building an app for tracking in the background all the visits so that we can do timekeeping based on GPS. I have created an service which is managing this. In the past we have used
locationManager.delegate = self
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.allowsBackgroundLocationUpdates = true
locationManager.showsBackgroundLocationIndicator = true
locationManager.requestAlwaysAuthorization()
locationManager.startMonitoringVisits();
Problem with this function is that is does not work good enough. So we have made our own which is started from swift UI interface and fetching an coord every 5 minutes and then compares with the previous one. This is working properly.
But the another problem arises is that when the app is swiped away the process is getting killed. But for some reason we cannot find the solution to make sure that IOS is started the process again automatically in background when the app is killed.
We have changed the app delegate to take care of this but this solution does not appear to work:
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.myapp.refresh", using: nil) { task in
self.handleBackgroundFetch(task: task as! BGAppRefreshTask)
}
scheduleBackgroundFetch()
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
scheduleBackgroundFetch()
}
func scheduleBackgroundFetch() {
let request = BGAppRefreshTaskRequest(identifier: "com.myapp.refresh")
request.earliestBeginDate = Date(timeIntervalSinceNow: 5 * 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: (error)")
}
}
func handleBackgroundFetch(task: BGAppRefreshTask) {
scheduleBackgroundFetch()
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
let operation = BlockOperation {
MyAppGeoFenceLocationManager.shared.runLocationManager()
}
task.expirationHandler = {
queue.cancelAllOperations()
}
queue.addOperation(operation)
task.setTaskCompleted(success: !operation.isCancelled)
}
}
What is a proper way to solve this problem and run an service in background and restart when killed for whatever reason? Basically we want to recreate the startMonitoringVisits method in our own way with different logic. Thanks for the help!
Note:
- We added the com.myapp.refresh in the plist
- Onder Signing & Capabilities the Location Updates, Background fetch and Background processing are checked