Home > Enterprise >  CLLocationManagerDelegate functions not called
CLLocationManagerDelegate functions not called

Time:02-16

I have a separate class named LocationService

class LocationService: NSObject, CLLocationManagerDelegate {
    private var locationManager = CLLocationManager()
    private var locationCallback: ((CLLocation?) -> Void)!
    
    override init(){
        super.init()
        self.locationManager.delegate = self
    }
    
    public func getCurrentLocation (_ completion: @escaping(CLLocation?) -> Void) {
        if PermissionManager.hasLocationPermission() && CLLocationManager.locationServicesEnabled() {
            self.locationCallback = completion
            self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
            self.locationManager.startUpdatingLocation()
        } else {
            completion(nil)
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("LOCATIONS: ", locations)
        locationCallback(locations.first)
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("LOCATION ERROR: ", error)
        locationCallback(nil)
    }
    
    func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
        print("LOCATION: ", newLocation)
        locationCallback(newLocation)
    }
    
    deinit {
        print("DEINIT LOCATION SERVICE")
    }

}

If I trigger getCurrentLocation, none of the location manager delegate functions were called, although startUpdatingLocation was reached.

I have no view controller because it's inside a react native plugin. The Location When In Use Usage Description is set in the info.plist and the deinit function was never called. Furthermore, the location permission is also granted.

Does someone know what is missing?

CodePudding user response:

protocol LocationManagerDelegate {
func didAuthorized()
func didUpdateLocation(location: CLLocation?, isFirst: Bool)
}

final class LocationManager: NSObject {

static let shared = LocationManager()

let delegates = MulticastDelegate<LocationManagerDelegate>()

private var locationManager = CLLocationManager()

var currentLocation: CLLocation?

var isStop = false
var denied = false


override init() {
    super.init()

    self.locationManager.delegate = self
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
  }
}

func request() {
if CLLocationManager.locationServicesEnabled() {
    switch CLLocationManager.authorizationStatus() {
    case .notDetermined, .restricted, .denied:
        self.denied = true
        
        self.locationManager.requestWhenInUseAuthorization()
        
    case .authorizedAlways, .authorizedWhenInUse:
        self.isStop = false
        self.denied = false
        self.locationManager.startUpdatingLocation()
        
    default:
        break
    }
 }
}

func stop() {
self.isStop = true
self.locationManager.stopUpdatingLocation()
 }
}

This is extension

extension LocationManager: CLLocationManagerDelegate {

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    if status == .authorizedWhenInUse || status == .authorizedAlways {
        self.isStop = false

        if self.denied {
            self.denied = false
            self.locationManager.startUpdatingLocation()
            self.locationManager.requestAlwaysAuthorization()
        }
        self.delegates.invoke(invocation: { $0.didAuthorized() })
    }
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let location = locations.first, isStop == false else {
        return
    }

    var isFirst = false
    if self.currentLocation == nil {
        isFirst = true
    }

    self.currentLocation = location
    self.delegates.invoke(invocation: { $0.didUpdateLocation(location: location, isFirst: isFirst) })
}


func checkLocationPermission() -> Bool {
    
    // check the permission status
    switch CLLocationManager.authorizationStatus() {
    case .authorizedAlways, .authorizedWhenInUse:
        return true
    default:break
    }
    return false
 }
}

maybe you must use this: static let shared = LocationManager()

when I want location , I use: LocationManager.shared.request()

this works for me

CodePudding user response:

First you must ask permission from user

self.locationManager.requestWhenInUseAuthorization()

  • Related