Search code examples
iosswiftlocationmanager

Add CLLocationManagerDelegate to a separate class


I would like to remove the CLLocationManagerDelegate from my ViewController and add to a separate class and make it reusable. I'm quite new to swift so I'm asking your help maybe you can point me in the right direction.

My goal is to call my LocationHandler class every time when I want the user's location and most of the times I would like to handle the location differently (e.g. just save it as it is or other time check the location and if it meets certain rules then save it etc...)

I would like to pass in a function to my LocationHandler class if it possible to handle the location change.

something like this: (this is just a pseudo code, I don't know how to do it properly in swift)

let locationHandler = LocationHandler()

locationHandler.handleLocationChange = (locations: [CLLocation]) - > {...}

locationHandler.getCurrentLocation()

My first problem is when I create an instance from my LocationHandler the getCurrentLocation function is running properly but the didUpdateLocations never rise (I think there is something with the delegation)

Second is I have no idea how to pass a function into a class as a parameter

here is my LocationHandler class

import Foundation
import CoreLocation

class LocationHandler: NSObject, CLLocationManagerDelegate{
    
    let locationManager = CLLocationManager()
   
    
    override init(){
        super.init()
        
        locationManager.delegate = self
        
    }
    
    func getCurrentLocation(){
     
        if CLLocationManager.locationServicesEnabled() {
            switch CLLocationManager.authorizationStatus() {
                case .notDetermined, .restricted, .denied:
                    print("No access")
                case .authorizedAlways, .authorizedWhenInUse:
                    print("Access")
                @unknown default:
                break
            }
            } else {
                print("Location services are not enabled")
        }
        
        
        locationManager.requestWhenInUseAuthorization()
        locationManager.requestLocation()
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
          if let location = locations.first {
              print("Found user's location: \(location)")
              //do something with the location
          }
      }
      
      func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
          print("Failed to find user's location: \(error.localizedDescription)")
      }
    
    
    
}

and I use it in the viewcontroller like this:

  let locationHandler = LocationHandler()
  locationHandler.getCurrentLocation()

Solution

  • As written, you have to ensure that the LocationHandler instance is a property of the view controller, not a local variable. You want to make sure it doesn’t fall out of scope and is deallocated before the delegate method has a chance to be called.