Send Location of User in Background Swift - ios

I am building an app where the user clicks a button and for 60mins (or any amount of time) we keep track of them by uploading their location to a server. Currently we are using 'Did Update Locations' function to send the users location to firebase in real-time.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
This system works but it spams the server sending the location of the user to the server once every second.
This is too much data and we would only need to send the users location to the server once every 10-30 seconds.
What can we do send the users location once every 10-30 seconds?

class ViewController: UIViewController, CLLocationManagerDelegate {
private var locman = CLLocationManager()
private var startTime: Date? //An instance variable, will be used as a previous location time.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let loc = locations.last else { return }
let time = loc.timestamp
guard var startTime = startTime else {
self.startTime = time // Saving time of first location, so we could use it to compare later with second location time.
return //Returning from this function, as at this moment we don't have second location.
}
let elapsed = time.timeIntervalSince(startTime) // Calculating time interval between first and second (previously saved) locations timestamps.
if elapsed > 30 { //If time interval is more than 30 seconds
print("Upload updated location to server")
updateUser(location: loc) //user function which uploads user location or coordinate to server.
startTime = time //Changing our timestamp of previous location to timestamp of location we already uploaded.
}
}

import UIKit
import CoreLocation
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,CLLocationManagerDelegate {
var window: UIWindow?
var locationManager = CLLocationManager()
var backgroundUpdateTask: UIBackgroundTaskIdentifier!
var bgtimer = Timer()
var latitude: Double = 0.0
var longitude: Double = 0.0
var current_time = NSDate().timeIntervalSince1970
var timer = Timer()
var f = 0
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.doBackgroundTask()
return true
}
func applicationWillResignActive(_ application: UIApplication) {
}
func applicationWillEnterForeground(_ application: UIApplication) {
print("Entering foreBackground")
}
func applicationDidBecomeActive(_ application: UIApplication) {
}
func applicationWillTerminate(_ application: UIApplication) {
}
func applicationDidEnterBackground(_ application: UIApplication) {
print("Entering Background")
// self.doBackgroundTask()
}
func doBackgroundTask() {
DispatchQueue.main.async {
self.beginBackgroundUpdateTask()
self.StartupdateLocation()
self.bgtimer = Timer.scheduledTimer(timeInterval:-1, target: self, selector: #selector(AppDelegate.bgtimer(_:)), userInfo: nil, repeats: true)
RunLoop.current.add(self.bgtimer, forMode: RunLoopMode.defaultRunLoopMode)
RunLoop.current.run()
self.endBackgroundUpdateTask()
}
}
func beginBackgroundUpdateTask() {
self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
self.endBackgroundUpdateTask()
})
}
func endBackgroundUpdateTask() {
UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
self.backgroundUpdateTask = UIBackgroundTaskInvalid
}
func StartupdateLocation() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.requestAlwaysAuthorization()
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Error while requesting new coordinates")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
self.latitude = locValue.latitude
self.longitude = locValue.longitude
f+=1
print("New Coordinates: \(f) ")
print(self.latitude)
print(self.longitude)
}
#objc func bgtimer(_ timer:Timer!){
sleep(2)
/* if UIApplication.shared.applicationState == .active {
timer.invalidate()
}*/
self.updateLocation()
}
func updateLocation() {
self.locationManager.startUpdatingLocation()
self.locationManager.stopUpdatingLocation()
}}
I added the sleep function to delay of calling the location and send the information to server
Since this is running in both the app is active and goes to background. If you want only background process, remove or comment the function self.doBackgroundTask() from didFinishLaunchingWithOptions and remove the comment for self.doBackgroundTask() in the applicationdidEnterBackground. And then remove the comment in the function bgtimer(), since the background process has to stop once the app comes to active state.

Apps normally get suspended (no longer get CPU time) a moment after being moved to the background. You can ask for extra background time, but the system only gives you 3 minutes.
Only a very limited class of apps are allowed to run in the background for longer than that. Mapping/GPS applications are one of those categories. However, your app is not a mapping/GPS application, so I doubt if Apple would approve it.
Bottom line: I think you might be out of luck running your location queries for more than 3 minutes.
EDIT:
As Paulw11 points out, you can use the significant location change service to get location updates when the device moves by large distances.

Related

Sending location to server in background every x minutes

I would like to send the device's location to a server every x minutes, even if the location does not change, while the app is in the background. (most optimal timeframe would be like 1.5 - 2 hours)
Currently it gets terminated after 30 sec.
I have seen some articles about adding these to the AppDelegate's didFinishLaunchingWithOptions method:
application.setMinimumBackgroundFetchInterval(1800)
UIApplication.shared.setMinimumBackgroundFetchInterval(1800)
but it got deprecated in iOS 13.
The AppDelegate looks like this:
import UIKit
#main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var backgroundUpdateTask: UIBackgroundTaskIdentifier!
var backgroundTaskTimer: Timer! = Timer()
var locationManager: LocationManager!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
locationManager = LocationManager()
let coordinator = AppCoordinator(window: window)
coordinator.start()
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
doBackgroundTask()
}
func applicationWillEnterForeground(_ application: UIApplication) {
if backgroundTaskTimer != nil {
backgroundTaskTimer.invalidate()
backgroundTaskTimer = nil
}
}
#objc func startTracking() {
self.locationManager.sendLocation()
}
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: AppEnvironment.backgroundTimeInterval,
target: self, selector: #selector(self.startTracking),
userInfo: nil, repeats: true)
RunLoop.current.add(self.backgroundTaskTimer, forMode: RunLoop.Mode.default)
RunLoop.current.run()
// End the background task.
self.endBackgroundTask()
}
}
func beginBackgroundTask() {
backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(withName: "Track trip", expirationHandler: {
self.endBackgroundTask()
})
}
func endBackgroundTask() {
UIApplication.shared.endBackgroundTask(backgroundUpdateTask)
backgroundUpdateTask = UIBackgroundTaskIdentifier.invalid
}
}
The LocationManager looks like this:
import Foundation
import CoreLocation
class LocationManager: NSObject, CLLocationManagerDelegate {
private let locationService: LocationServiceProtocol
private let manager = CLLocationManager()
private var lastLocation: Coordinate?
private var offlineCoordinates: [Coordinate] = []
init(locationService: LocationServiceProtocol = LocationService()) {
self.locationService = locationService
}
func sendLocation() {
manager.delegate = self
manager.requestLocation()
}
private func handleLocation() {
guard let coordinate = lastLocation else { return }
guard Connectivity.isConnectedToTheInternet else {
offlineCoordinates.append(coordinate)
return
}
if !offlineCoordinates.isEmpty {
offlineCoordinates.forEach { postCoordinate($0) }
offlineCoordinates.removeAll()
}
postCoordinate(coordinate)
}
private func postCoordinate(_ coordinate: Coordinate) {
locationService.sendLocation(coordinate) { [weak self] result in
guard self != nil else { return }
switch result {
case .failure(let error):
print(error.localizedDescription)
case .success(_):
print("Location sent.")
}
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation()
manager.delegate = nil
guard let location = locations.first else { return }
let latitude = location.coordinate.latitude
let longitude = location.coordinate.longitude
print("\tLatitude: \(latitude), Longitude: \(longitude)")
lastLocation = Coordinate(lat: latitude, lon: longitude,
supervisorNfc: GlobalAppStorage.shared.defaults.string(forKey: Constants.StorageKeys.supervisorNfc) ?? "")
handleLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
}
In Background Modes the following are enabled:
• Location updates
• Background fetch
• Background processing
In Info.plist I have set the following properties:
• Privacy - Location Usage Description
• Privacy - Location When In Use Usage Description
• Privacy - Location Always and When In Use Usage Description
• and the above mentioned under the Required background modes.
Thanks in advance for your help!

Location coordinates are not nill yet labels don't get updated when app is loaded but get loaded if I come back from another screen tho

I have defined a global variable to store location coordinates and im updating location in Appdelegate as soon as the app launches. Here's the code for that:
var locationManager:CLLocationManager!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
determineCurrentLocation()
self.pushToHomeScreen()
return true
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if GlobalUserManager.shared.currentLocation == nil {
GlobalUserManager.shared.currentLocation = locations.last
locationManager.stopUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Error - locationManager: \(error.localizedDescription)")
}
//MARK:- Intance Methods
func determineCurrentLocation() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
}
}
After this the Home Screen opens where I have two labels to show location data. It didn't get update when Homescreen is loaded for both cases when I tried to update by putting code in viewdidLoad() and viewWillAppear(). So I tried putting code in viewDidAppear() and its something like this:
override func viewDidAppear(_ animated: Bool) {
if GlobalUserManager.shared.currentLocation != nil {
lblLat.text = GlobalUserManager.shared.currentLocation.latitude
lblLong.text = GlobalUserManager.shared.currentLocation.longitude
}
else {
lblLat.text = "Lat not available"
lblLong.text = "Long not available"
}
}
When screen is loaded, labels are empty which means at least GlobalUserManager.shared.currentLocation != nil but I want them to get updated as soon as screen is loaded. Instead I have to click another page and come back and then they are updated.

Retrieving the current location of the user/ retrieving the values of longitude and latitude watchkit/ios swift

I want to obtain the current location (longitude and latitude) of the user, but I just get 0 for both of the variables. I do not know where the problem lies in. I am following this tutorial and have updated the infop.list of the app folder and the watch extension folder (NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription), inserted the needed Watchconnector to both of the folders with cocoapods, and I also have added the Corelocation framework via link binary with libraries.
I have little knowledge about swift and watch os, I hope anyone can help.
Here is the project file: https://ufile.io/l5elkpsw
Thank you very much.
And here are my Appdelegate and Interfacecontroller file:
import UIKit
import CoreLocation
import MapKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {
let locationManager:CLLocationManager = CLLocationManager()
var currentLocation = CLLocation()
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
WatchConnector.shared.activateSession()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestLocation()
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
return true
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locations.count == 0
{
return
}
self.currentLocation = locations.first!
let message = ["lat":self.currentLocation.coordinate.latitude,"long":self.currentLocation.coordinate.longitude]
WatchConnector.shared.sendMessage(message, withIdentifier: "sendCurrentLocation") { (error) in
print("error in send message to watch\(error.localizedDescription)")
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Fail to load location")
print(error.localizedDescription)
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// 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.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// 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.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
import WatchKit
import Foundation
import CoreLocation
class InterfaceController: WKInterfaceController{
private let locationAccessUnauthorizedMessage = "Locations Disabled\n\nEnable locations for this app via the Settings in your iPhone to see meetups near you!"
private let pendingAccessMessage = "Grant location access to GPS dummy"
#IBOutlet weak var map: WKInterfaceMap!
#IBOutlet weak var button: WKInterfaceButton!
#IBOutlet weak var latitudeL: WKInterfaceLabel!
#IBOutlet weak var longitudeL: WKInterfaceLabel!
#IBOutlet weak var authorizeL: WKInterfaceLabel!
var currentLocation = CLLocation()
let locationManager = CLLocationManager()
var lat: Double = 0.0
var long: Double = 0.0
override func awake(withContext context: Any?) {
super.awake(withContext: context)
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// Configure interface objects here.
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
WatchConnector.shared.listenToMessageBlock({ (message) in
self.lat = message["lat"] as! Double
self.long = message["long"] as! Double
print(self.lat)
print(self.long)
self.currentLocation = CLLocation(latitude: self.lat as! CLLocationDegrees, longitude: self.long as! CLLocationDegrees)
let mylocation : CLLocationCoordinate2D = CLLocationCoordinate2DMake(self.currentLocation.coordinate.latitude, self.currentLocation.coordinate.longitude)
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let region = MKCoordinateRegion(center: mylocation, span: span)
self.map.setRegion(region)
self.map.addAnnotation(mylocation, with: .red)
}, withIdentifier: "sendCurrentLocation")
let authorizationStatus = CLLocationManager.authorizationStatus()
handleLocationServicesAuthorizationStatus(authorizationStatus)
}
func handleLocationServicesAuthorizationStatus(_ status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
print("handleLocationServicesAuthorizationStatus: .undetermined")
handleLocationServicesStateNotDetermined()
case .restricted, .denied:
print("handleLocationServicesAuthorizationStatus: .restricted, .denied")
handleLocationServicesStateUnavailable()
case .authorizedAlways, .authorizedWhenInUse:
print("handleLocationServicesAuthorizationStatus: .authorizedAlways, .authorizedWhenInUse")
handleLocationServicesStateAvailable(status)
}
}
func handleLocationServicesStateNotDetermined() {
authorizeL.setText(pendingAccessMessage)
locationManager.requestWhenInUseAuthorization()
}
func handleLocationServicesStateUnavailable() {
authorizeL.setText(locationAccessUnauthorizedMessage)
}
func handleLocationServicesStateAvailable(_ status: CLAuthorizationStatus) {
switch status {
case .authorizedAlways:
locationManager.startUpdatingLocation()
case .authorizedWhenInUse:
locationManager.requestLocation()
default:
break
}
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
#IBAction func btnPressed() {
self.latitudeL.setText("\(self.lat)")
self.longitudeL.setText("\(self.long)")
print("\(locationManager.requestLocation())")
print("\(self.lat)")
print("\(self.long)")
}
}
extension InterfaceController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("error:: \(error.localizedDescription)")
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
locationManager.requestLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locations.first != nil {
print("location:: (location)")
}
}
}
Are you testing on a simulator? If so, you might need to set the location to something in the Debug/Location menu:

Location does not update after application comes back from background

I am building an app where I want to keep track of updated user location whenever the app comes back from background.
I wrote my location tracking code in AppDelegate's didFinishLaunchingWithOptions method
//Core Location Administration
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 70
locationManager.requestAlwaysAuthorization()
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.startMonitoringVisits()
locationManager.delegate = self
Since I was not able to validate Visits, I added the standard location tracking too
locationManager.allowsBackgroundLocationUpdates = true
locationManager.startUpdatingLocation()
I created CLLocationManagerDelegate block and added the following code
extension AppDelegate: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didVisit visit: CLVisit) {
let clLocation = CLLocation(latitude: visit.coordinate.latitude, longitude: visit.coordinate.longitude)
// Get location description
AppDelegate.geoCoder.reverseGeocodeLocation(clLocation) { placemarks, _ in
if let place = placemarks?.first {
let description = "\(place)"
self.newVisitReceived(visit, description: description)
}
}
}
func newVisitReceived(_ visit: CLVisit, description: String) {
let location = Location(visit: visit, descriptionString: description)
LErrorHandler.shared.logInfo("\(location.latitude), \(location.longitude)")
UserModal.shared.setUserLocation(location)
UserModal.shared.userLocationUpdated = Date()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.first else {
return
}
locationManager.stopUpdatingLocation()
let uL = Location(location:location.coordinate, descriptionString: "")
LErrorHandler.shared.logInfo("\(uL.latitude), \(uL.longitude)")
UserModal.shared.setUserLocation(uL)
UserModal.shared.userLocationUpdated = Date()
}
}
I added this code to begin location tracking when the app comes to foreground
func applicationWillEnterForeground(_ application: UIApplication) {
// 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.
locationManager.startUpdatingLocation()
}
If I am on a ViewController and the application goes back to the background, it does not refresh the location when the app comes to foreground.
Can someone suggest a better way to do this?
You should write code for location in didbecomeActive method of App delegate not in didFinishLaunchingWithOptions. Try this hope it will help.

Get User Location Every 5 minutes with background modes in Swift 3

I want to ;
Get User Location Every 5 minutes with background modes in Swift 3
But my codes don't any action. I need to get and send server ,longitude , latitude , and altitude values every 5 minutes
My codes under below.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
sleep(2)
BackgroundLocationManager.instance.start()
return true
}
BackgroundLocationManager - Class
import Foundation
import CoreLocation
import UIKit
class BackgroundLocationManager :NSObject, CLLocationManagerDelegate {
static let instance = BackgroundLocationManager()
static let BACKGROUND_TIMER = 15.0 // restart location manager every 150 seconds
static let UPDATE_SERVER_INTERVAL = 60 * 5 // 5 minutes server send
let locationManager = CLLocationManager()
var timer:Timer?
var currentBgTaskId : UIBackgroundTaskIdentifier?
var lastLocationDate : NSDate = NSDate()
private override init(){
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.activityType = .other;
locationManager.distanceFilter = kCLDistanceFilterNone;
if #available(iOS 9, *){
locationManager.allowsBackgroundLocationUpdates = true
}
NotificationCenter.default.addObserver(self, selector: #selector(self.applicationEnterBackground), name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
}
func applicationEnterBackground(){
// FileLogger.log("applicationEnterBackground")
start()
}
func start(){
if(CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways){
if #available(iOS 9, *){
locationManager.requestLocation()
} else {
locationManager.startUpdatingLocation()
}
} else {
locationManager.requestAlwaysAuthorization()
}
}
func restart (){
timer?.invalidate()
timer = nil
start()
}
private func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case CLAuthorizationStatus.restricted: break
//log("Restricted Access to location")
case CLAuthorizationStatus.denied: break
//log("User denied access to location")
case CLAuthorizationStatus.notDetermined: break
//log("Status not determined")
default:
//log("startUpdatintLocation")
if #available(iOS 9, *){
locationManager.requestLocation()
} else {
locationManager.startUpdatingLocation()
}
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if(timer==nil){
// The locations array is sorted in chronologically ascending order, so the
// last element is the most recent
guard locations.last != nil else {return}
beginNewBackgroundTask()
locationManager.stopUpdatingLocation()
let now = NSDate()
if(isItTime(now: now)){
//TODO: Every n minutes do whatever you want with the new location. Like for example sendLocationToServer(location, now:now)
}
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
beginNewBackgroundTask()
locationManager.stopUpdatingLocation()
}
func isItTime(now:NSDate) -> Bool {
let timePast = now.timeIntervalSince(lastLocationDate as Date)
let intervalExceeded = Int(timePast) > BackgroundLocationManager.UPDATE_SERVER_INTERVAL
return intervalExceeded;
}
func sendLocationToServer(location:CLLocation, now:NSDate){
//TODO
}
func beginNewBackgroundTask(){
var previousTaskId = currentBgTaskId;
currentBgTaskId = UIApplication.shared.beginBackgroundTask(expirationHandler: {
// FileLogger.log("task expired: ")
})
if let taskId = previousTaskId{
UIApplication.shared.endBackgroundTask(taskId)
previousTaskId = UIBackgroundTaskInvalid
}
timer = Timer.scheduledTimer(timeInterval: BackgroundLocationManager.BACKGROUND_TIMER, target: self, selector: #selector(self.restart),userInfo: nil, repeats: false)
}
}

Resources