2

For some reason didUpdateLocations is not being called, even when I set the delegate to the view controller. In info.plist I set the key Privacy - Location When In Use Usage Description to a description. So I'm not sure what I could be doing wrong?

import MapKit
import CoreLocation

class OptionsViewController: UIViewController, UITableViewDelegate, CLLocationManagerDelegate {
    override func viewDidLoad() {
          //Ask user for location
        locationManager = CLLocationManager()
        locationManager.requestWhenInUseAuthorization()

        //Use users current location if no starting point set
        if CLLocationManager.locationServicesEnabled() {
            let locationManager = CLLocationManager()
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.startUpdatingLocation()
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        locationManager = CLLocationManager()
        locationManager.requestWhenInUseAuthorization()
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error){
        locationManager.stopUpdatingLocation()
        print(error)
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("Did update location called?")
        let locValue:CLLocationCoordinate2D = manager.location!.coordinate
        print("locations = \(locValue.latitude) \(locValue.longitude)")
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
14wml
  • 4,048
  • 11
  • 49
  • 97
  • the problem is where you declared locationManager. You need to declare it as a property of your view controller – Leo Dabus Apr 19 '17 at 01:54
  • BTW this is not your actual code. Where is locationManager declared? Your code can't compile as it is – Leo Dabus Apr 19 '17 at 01:57
  • Your problem is `let locationManager = CLLocationManager()` inside the method creates a new local variable locationManager that goes out of existence once the viewDidLoad method finishes – Leo Dabus Apr 19 '17 at 02:00
  • No need to import CoreLocation if you are already importing MapKit – Leo Dabus Apr 19 '17 at 04:08

1 Answers1

1

Problem is here:

  override func viewDidAppear(_ animated: Bool) {
      locationManager = CLLocationManager()
      locationManager.requestWhenInUseAuthorization()
  }

This method will be called after viewDidLoad, but you new created a locationManager later in viewDidAppear and not pointed its delegate to self. That's why the delegate(self)'s methods is not be called.

The improved but not the best way is:

class OptionsViewController: UIViewController, UITableViewDelegate, CLLocationManagerDelegate {

    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        //Ask user for location
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest

        //Use users current location if no starting point set
        if CLLocationManager.locationServicesEnabled() {
            if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse
              || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways {
                locationManager.startUpdatingLocation()
            }
            else{
                locationManager.requestWhenInUseAuthorization()
            }
        }
        else{
            //Alert user to open location service, bra bra bra here...
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        //... nothing need to do for location here
    }

    public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == CLAuthorizationStatus.authorizedWhenInUse
          || status == CLAuthorizationStatus.authorizedAlways {
            locationManager.startUpdatingLocation()
        }
        else{
            //other procedures when location service is not permitted.
        }
    }

    //......
}
Yun CHEN
  • 6,450
  • 3
  • 30
  • 33
  • `locationManager = CLLocationManager()` ????? Not a `var` or `let`. just throw code and see what happen – Leo Dabus Apr 19 '17 at 02:00
  • now it is optional you need to change the rest of the code – Leo Dabus Apr 19 '17 at 02:02
  • your update now has some errors due to the last update – Leo Dabus Apr 19 '17 at 02:03
  • I updated it again, it should not have errors now, thanks for suggestions, ;) – Yun CHEN Apr 19 '17 at 02:23
  • I've copy and pasted ur code but the `didUpdateLocations` never gets called still... – 14wml Apr 19 '17 at 02:36
  • Make breakpoint on sentence "locationManager.startUpdatingLocation()" and "locationManager.requestWhenInUseAuthorization()", to check if they are called. – Yun CHEN Apr 19 '17 at 02:47
  • @YunCHEN In `viewDidLoad()` in the `if CLLocationManager.locationServicesEnabled() {` I put a break point at `locationManager.startUpdatingLocation()` and it does hit that break point – 14wml Apr 19 '17 at 03:22
  • @YunCHEN In `public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus)` I also put a breakpoint at ` locationManager.startUpdatingLocation()` and it does hit that break point – 14wml Apr 19 '17 at 03:23
  • @YunCHEN however when I put break point at `didUpdateLocations` it never hits that one – 14wml Apr 19 '17 at 03:23
  • @YunCHEN Do u know why that might be? – 14wml Apr 19 '17 at 03:24
  • @15ongm, to check if the location service is closed or not, in iPhone settings: "Privacy"/"Location service". And it's better not run app on Simulator. – Yun CHEN Apr 19 '17 at 05:33