CLLocationManager delegate methods are not getting

2019-01-09 20:40发布

问题:

The delegate Methods of CLLocationManager

didChangeAuthorizationStatus and didUpdateToLocation

are not getting called.

Location Always Usage Description key is already added in info.plist and I am getting notification also when i launch app for the first time.

I am able to see the google map, but i am not able to see current location, When i change location, its not getting updated. Basicaaly delegate methods are not getting called.

//code

import UIKit
import GoogleMaps

class ViewController: UIViewController,GMSMapViewDelegate {
    @IBOutlet weak var mapViewTest: GMSMapView!
    let locationManager = CLLocationManager()
    var currentLocation :CLLocation = CLLocation(latitude: 0.0, longitude: 0.0)
    var currentLatitude : Double = 0.0
    var currentLongitude : Double = 0.0
    override func viewDidLoad() 
     {
        super.viewDidLoad()``
        locationManager.delegate = self
        if (CLLocationManager.locationServicesEnabled())
        {
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.allowsBackgroundLocationUpdates = true
        locationManager.requestAlwaysAuthorization()
        locationManager.startUpdatingLocation()
        }
        // Do any additional setup after loading the view, typically from a nib.
    }
}


    extension ViewController : CLLocationManagerDelegate
    {
       func locationManager(manager: CLLocationManager,     didChangeAuthorizationStatus status: CLAuthorizationStatus)
        {
            if status == .authorizedAlways
            {
                if(CLLocationManager .locationServicesEnabled())
                {
                    locationManager.startUpdatingLocation()
                    mapViewTest.isMyLocationEnabled = true
                    mapViewTest.settings.myLocationButton = true
                }
            }
        }
         func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation)
        {
            mapViewTest.camera = GMSCameraPosition(target: (newLocation.coordinate), zoom: 15, bearing: 0, viewingAngle: 0)
            currentLocation = newLocation
            currentLatitude = newLocation.coordinate.latitude
            currentLongitude = newLocation.coordinate.longitude

        }
        func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
        {
            print("Errors: " + error.localizedDescription)
        }
    }

回答1:

From your code you are working with Swift 3, and in Swift 3 CLLocationManagerDelegate method's signature is changed like this.

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {

}

//func locationManager(_ manager: CLLocationManager, didUpdateTo newLocation: CLLocation, 
       from oldLocation: CLLocation) is deprecated with below one
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

}

Check Apple Documentation on CLLocationManagerDelegate for more details.



回答2:

After checking your code i found some changes you needs to do as follow,

note : I have only added the code having issue here that of location manager

import UIKit
import CoreLocation

class ViewController: UIViewController {

    let locationManager = CLLocationManager()

    var currentLocation :CLLocation = CLLocation(latitude: 0.0, longitude: 0.0)
    var currentLatitude : Double = 0.0
    var currentLongitude : Double = 0.0

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

        locationManager.delegate = self
        if (CLLocationManager.locationServicesEnabled())
        {
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.allowsBackgroundLocationUpdates = true
            locationManager.requestAlwaysAuthorization()
            locationManager.startUpdatingLocation()
        }
    }

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

}

extension ViewController : CLLocationManagerDelegate {

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    }

    func locationManager(_ manager: CLLocationManager, didFinishDeferredUpdatesWithError error: Error?) {
        print("Errors: " + (error?.localizedDescription)!)
    }
}

Also add below lines in .plist file if not added,

   <key>NSLocationWhenInUseUsageDescription</key>
   <string>$(PRODUCT_NAME) location use</string>
   <key>NSLocationAlwaysUsageDescription</key>
   <string>$(PRODUCT_NAME) always uses location </string>


回答3:

Add these two properties in your info.plist

NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription


回答4:

you need to put the mapview delegate to self.

try this:

  override func viewDidLoad() {
    super.viewDidLoad()

    // User Location Settings
    locationManager.delegate = self
    locationManager.requestWhenInUseAuthorization()
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.startUpdatingLocation()

    // Google Maps Delegate
    mapView.delegate = self
}

// View will appear
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // Google maps settings
    mapView.isMyLocationEnabled = true
    mapView.settings.myLocationButton = true

    // Get location if autorized
    if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse) {
        let (latitude, longitude) = self.getLocation()
        mapView.camera = GMSCameraPosition.camera(
            withLatitude: latitude,
            longitude: longitude,
            zoom: 14)
    }
}


    //Get the user location
    func getLocation() -> (latitude: CLLocationDegrees, longitude: CLLocationDegrees) {

    let latitude = (locationManager.location?.coordinate.latitude)!
    let longitude = (locationManager.location?.coordinate.longitude)!

    return (latitude, longitude)
}