Swift: location not updating when returning from background

I have a Swift app that I'm trying to update when the app returns from the background, but it doesn't work when it returns from the background.

When I run the app, I get the location just fine. After getting the location, I call stopUpdatingLocation (), so I won't keep getting the location: locationManager.stopUpdatingLocation ()

Then, in my AppDelegate.swift, run UpdatingLocation again:

func applicationWillEnterForeground(application: UIApplication) {

    ViewController().locationManager.startUpdatingLocation()
}

      

This is my code:

import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

var locationManager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    println("Error while updating location " + error.localizedDescription)
}

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {

    var userLocation:CLLocation = locations[0] as CLLocation

    println("\(userLocation.coordinate.latitude),\(userLocation.coordinate.longitude)")

    locationManager.stopUpdatingLocation()

}

}

      

However, whenever I use the app (press Home) and then go back to the app, the location will not be updated. Any idea what I might be doing wrong here?

+1


source to share


1 answer


The applicationWillEnterForeground

code creates a new local instance ViewController

that is never displayed, has not yet been created, locationManager

and therefore has no effect.

This does not apply to an instance ViewController

that already exists and is displayed (and has an instance locationManager

that was originally started).

Instead, it should get a reference to an existing instance. Assuming that ViewController

is the root view controller, you can do:

func applicationWillEnterForeground(application: UIApplication) {

    if let rvc = window?.rootViewController as? ViewController {
        rvc.locationManager.startUpdatingLocation()
    }

}

      




However, it would be better to let the class ViewController

manage its own behavior. Thus, the application delegate does not have to look for a reference to the view controller instance, and it does not have direct access to the internal state of the view controller, but ViewController

becomes more self-contained.

In addition to the application delegation method applicationWillEnterForeground

, you can monitor these events from anywhere using notification UIApplicationWillEnterForegroundNotification

.

In ViewController

you can register and deregister for notification in (for example) viewWillAppear

and viewWillDisappear

. When registering, you specify which method to call for the event, and everything is processed internally ViewController

(and the code in applicationWillEnterForeground

can be deleted).

override func viewWillAppear(animated: Bool) {
    NSNotificationCenter.defaultCenter().addObserver(
        self, 
        selector: "willEnterForegound", 
        name: UIApplicationWillEnterForegroundNotification, 
        object: nil)
}

override func viewWillDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(
        self, 
        name: UIApplicationWillEnterForegroundNotification, 
        object: nil)
}

func willEnterForegound() {
    locationManager.startUpdatingLocation()
}

      

+2


source







All Articles