0

I want the location to update every 3 minutes. The background task works after 3 minutes the first time, but doesn't restart after that. I need it to happen repeatedly and not once.

override func viewDidLoad()
    {
        super.viewDidLoad()
        timer.invalidate()
        timer = Timer.scheduledTimer(timeInterval: 179, target: self, selector: #selector(someBackgroundTask), userInfo: nil, repeats: true);
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        if CLLocationManager.locationServicesEnabled()
        {
            if status == CLAuthorizationStatus.notDetermined
            {
                locationManager.requestAlwaysAuthorization()
            }
        }else {
                print("locationServices disenabled")
            }
            self.locationManager.startUpdatingLocation()
            self.mapView.showsUserLocation = true
            mapView.delegate = self
        registerBackgroundTask()
    }
func someBackgroundTask(timer:Timer) {
        DispatchQueue.global(qos: .background).async {
            self.locationManager.startUpdatingLocation()
            timer.invalidate()
            timer.fire()
            self.registerBackgroundTask()
        }
    }
    func registerBackgroundTask() {
        backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
            self?.someBackgroundTask(timer: (self?.timer)!)
            self?.endBackgroundTask()
        }
        assert(backgroundTask != UIBackgroundTaskInvalid)
    }
    func endBackgroundTask() {
        print("Background task ended.")
        UIApplication.shared.endBackgroundTask(backgroundTask)
        backgroundTask = UIBackgroundTaskInvalid
    }
Steve
  • 1,121
  • 1
  • 12
  • 32
  • You can't run tasks on a time schedule in the background. You should either enable background location updates to receive updates when the user moves or if you need lower accuracy and lower battery impact then use significant location updates – Paulw11 Nov 22 '16 at 09:40

2 Answers2

2

After you call timer.invalidate you have to set your timer again with Timer.scheduledTimer(...).

Check the reference https://developer.apple.com/reference/foundation/timer/1415405-invalidate

Stopping a Timer func invalidate() Stops the receiver from ever firing again and requests its removal from its run loop.

Elena
  • 829
  • 8
  • 20
2

You need to enable CLLocationManager's allowsBackgroundLocationUpdates .

In Swift 2 you'll also need:

self.locationManager.allowsBackgroundLocationUpdates = true 

check this for more :https://stackoverflow.com/a/36194283/3901620

Community
  • 1
  • 1
KKRocks
  • 8,222
  • 1
  • 18
  • 84