swiftclasscllocationmanagercode-separation

Location Manager in seperate class in Swift


so I am currently working on some project and I encountered this issue. If I use CLLocationDelegate in ViewController, it runs normally, however when I try to separate this in its own class, it just doesn't work. When I try to run it just doesn't run the function bellow. Any advice is appreciated :)

View controller:

import UIKit
import CoreLocation
import Alamofire
import SwiftyJSON

class TodayViewController: UIViewController {

var locationManager = CLLocationManager()
override func viewDidLoad() {
    super.viewDidLoad()
 locationRequest.init()
    }    
 }

LocationManager class:

    import Foundation
    import CoreLocation

 class locationRequest: NSObject, CLLocationManagerDelegate {
var locationManager = CLLocationManager()

override init() {
    
    print("before super.init()")
    
    super.init()
    
    print("after super.init()")
    
    if CLLocationManager.locationServicesEnabled() {
        print("before setting delegate")
        locationManager.delegate = self
        
        locationManager.requestWhenInUseAuthorization()
        print("after setting delegate")
        locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
        locationManager.startUpdatingLocation()
    }
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    print("didUpdate")
    if let location: CLLocationCoordinate2D = manager.location?.coordinate {
        print(location.latitude)
        print(location.longitude)
          }
       }

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print("didFail")
    print(error.localizedDescription)
      }
   }

Solution

  • First of all please name custom structs and classes with starting uppercase letter.

    The error occurs because there is no strong reference to the locationRequest class.

    Either design the class as singleton

    class LocationRequest: NSObject, CLLocationManagerDelegate {
    
        static let shared = LocationRequest()
    
        ...   
    
    }
    
    ...
    
    class TodayViewController: UIViewController {
    
        var locationRequest = LocationRequest.shared
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }    
    

    or create a lazy instantiated property

    class LocationRequest: NSObject, CLLocationManagerDelegate { ... }
    
    ...
    
    class TodayViewController: UIViewController {
    
        lazy var locationRequest = LocationRequest()
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }    
    }