skip to Main Content

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?

2

Answers


  1. First you must ask permission from user

    self.locationManager.requestWhenInUseAuthorization()

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search