Swift + didUpdateUserLocation not getting called

4.1k views Asked by At

I am not able to call MKMapView delegate method didUpdateUserLocation.

What I did so far:

  1. Add framework MapKit.framwork in project

  2. Import framework in view controller by import MapKit line

  3. Add key in plist file

    <key>NSLocationAlwaysUsageDescription</key> <true/>

  4. Code in view controller

Added delegate didUpdateUserLocation method to check location is updated or not but never called.

// MARK: - MapView delegate methods

func mapView(mapView: MKMapView!, regionDidChangeAnimated animated: Bool) {
    // Calling...
}

func mapView(mapView: MKMapView!, didUpdateUserLocation userLocation: MKUserLocation!) {
   // Not getting called
}

// MARK: - View lifeCycle methods   
override func viewDidLoad() {
    super.viewDidLoad()
    var locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()

    locationManager.startUpdatingLocation()

    self.mapView.delegate = self
    self.mapView.showsUserLocation = true
    self.mapView.pitchEnabled = true
    self.mapView.showsBuildings = true
}

I have used simulator and change simulator custom location to check whether it is called or not? The method regionDidChangeAnimated is called perfectly!.

The same thing works for iOS7. what additional effort is remains for Swift map location update?

Edit: Plist keys

enter image description here

Also permission alert not prompted.

6

There are 6 answers

1
rintaro On BEST ANSWER
  1. You have to keep the reference to CLLocationManager.
  2. You have to wait locationManager(_:didChangeAuthorizationStatus:) delegate method called, before .startUpdatingLocation() and showsUserLocation = true.
  3. According to the document: NSLocationWhenInUseUsageDescription value type is String.

Try:

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    @IBOutlet weak var mapView: MKMapView!

    var locationManager = CLLocationManager()

    // MARK: - View lifeCycle methods
    override func viewDidLoad() {
        super.viewDidLoad()
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()

        self.mapView.delegate = self
        self.mapView.pitchEnabled = true
        self.mapView.showsBuildings = true
    }

    // MARK: - LocationManager delegate methods

    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch status {
        case .Authorized, .AuthorizedWhenInUse:
            manager.startUpdatingLocation()
            self.mapView.showsUserLocation = true
        default: break
        }
    }

    // MARK: - MapView delegate methods


    func mapView(mapView: MKMapView!, didUpdateUserLocation userLocation: MKUserLocation!) {
        println(userLocation)
        // Not getting called
    }

}
0
Gurjinder Singh On

After trying all above answer, if "didUpdateUserLocation" delegate not being called then choose simulator click on Debug from menu bar choose Location then choose Apple. I tried above all answer but location was set to custom, So I change it to Apple and delegate method called. After that i again set it to custom now it is showing location.

1
TheLittleHawk On

For applications that runs on iOS 8, you will need to add two keys in plist file:

NSLocationAlwaysUsageDescription (you already have this one)

NSLocationWhenInUseUsageDescription

Also you will need to wrap up check if app is running under iOS8 and if so add bellow two lines. If it is iOS 7 or under you will need to skip those two lines. If you forget to do this, app will crash on lower versions.

// You have this check
locationManager.requestWhenInUseAuthorization()
// Add this one
locationManager.requestAlwaysAuthorization()
2
Bhumit Mehta On

The problem is that you are asking for when in use authorization by

locationManager.requestWhenInUseAuthorization()

and in pList you are adding <key>NSLocationAlwaysUsageDescription</key> which is for always authorization . You need to use NSLocationWhenInUseUsageDescription Key

1
zisoft On

Besides the other answers I want to summarize here:

You have put the key NSLocationAlwaysUsageDescription in your info.plist. The value for that key must be a String containing the text of the question when the user gets prompted by the system to ask for location services permission.

According to the key, you must request the permission by calling

locationManager.requestWhenInUseAuthorization()

You probably may have answered the question so your answer may be already saved in the user preferences. The best way is to completely deinstall the app from the simulator and reinstall it so you will be asked again.

0
zhiyi On

fixed it!

After ios8 MKMapView did not load LocationCoordinate automatically。 If we want to use MKMapView to load the more accurate location with "-mapView:didUpdateUserLocation":

Premise: 1.setup the mapView delegate. 2.setShowsUserLocation:YES 3.mapView must in a container(addSubview:mapView)!!!!!

Example:

self.mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
_mapView.delegate = self;
[_mapView setShowsUserLocation:YES];
[[UIApplication sharedApplication].keyWindow addSubview:_mapView];


i add MapView to Window because the code in the UtilSingleton, you can add to your controller view generally.