i wanted callback for didEnterRegion and didExitRegion when user enters in location coordinates, as i am getting callback on location changes but not for geofence area, not sure why it is not working , Could someone pls helps in same.
import Foundation
import CoreLocation
import UIKit
class CoreLocationManager: NSObject, ObservableObject {
var locationManager : CLLocationManager?
@Published var currentLocation: CLLocation?
@Published var authorizationStatus: CLAuthorizationStatus = .notDetermined
var locations: [CoordinateModel] = [] {
didSet {
}
}
var locationCoordinates: [CLLocationCoordinate2D] = []
/// used to through the updates to corresponding Models, when there is changes occurs for the following properties
var locationUpdateHandler: ((CLLocation) -> Void)?
var authorizationStatusHandler: ((CLAuthorizationStatus) -> Void)?
var geoFenchCompletion: (((String),(String)) -> Void)?
override init() {
super.init()
NotificationCenter.default.addObserver(self, selector: #selector(handleAppStateChange), name: UIApplication.didBecomeActiveNotification, object: nil)
DispatchQueue.main.async {
self.setUpLocationManager()
}
}
func setUpLocationManager() {
if !isDeviceLocationEnabled() {
//// Perfoem action to update user that device location is off
/// This is device level permission access
return
}
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.startMonitoringSignificantLocationChanges()
locationManager?.requestWhenInUseAuthorization()
locationManager?.requestAlwaysAuthorization()
locationManager?.startUpdatingLocation()
addBackgroundFetching()
}
//MARK: GeoFench Area
//// as we have multiple coordinates which is used to notify user when her current location arrives / exit the lat long
/// here we are creating circular region with containing all lat long
func startMonitoring() {
for location in locations {
print(locations.count)
let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: location.latitude,
longitude: location.longitude),
radius: 150, identifier: location.title)
region.notifyOnEntry = true
region.notifyOnExit = true
print(region)
locationManager?.startMonitoring(for: region)
}
}
func addBackgroundFetching() {
locationManager?.requestAlwaysAuthorization()
locationManager?.allowsBackgroundLocationUpdates = true
}
}
//MARK: Location Manager Delegate
extension CoreLocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.first else { return }
print(location)
currentLocation = location
locationUpdateHandler?(currentLocation ?? CLLocation())
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
authorizationStatus = manager.authorizationStatus
authorizationStatusHandler?(locationManager?.authorizationStatus ?? .notDetermined)
locationManager?.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
if region is CLCircularRegion {
// Handle the event that the user entered a nearby location
print("Entered region: \(region.identifier)")
geoFenchCompletion?(("entered"), (region.identifier))
}
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
if region is CLCircularRegion {
// Handle the event that the user entered a nearby location
print("Leaving region: \(region.identifier)")
geoFenchCompletion?(("leaving"), (region.identifier))
}
}
}
// MARK: Location Permissions
extension CoreLocationManager {
func isDeviceLocationEnabled() -> Bool {
return CLLocationManager.locationServicesEnabled()
}
func isAppLocationDisabled() -> Bool {
if locationManager?.authorizationStatus == .denied {
return true
}
return false
}
@objc func handleAppStateChange() {
//// Intially when you launch app, user allow condition for location access, if user goes to setting application
/// and update appplication location access, here we will get callback and perform action accordingly
authorizationStatus = locationManager?.authorizationStatus ?? .notDetermined
authorizationStatusHandler?(locationManager?.authorizationStatus ?? .notDetermined)
locationManager?.startUpdatingLocation()
}
}
WindowGroup :
var body: some Scene {
WindowGroup {
CoordinatorView()
.onReceive(NotificationCenter.default.publisher(for: Notification.Name(Constants.NotificationNames.customerList))) { notification in
if let customerCoordinates = notification.userInfo?[Constants.NotificationNames.customerList] as? [CoordinateModel] {
let _ = print("==customerCoordinates==",customerCoordinates)
coreLocationManager = CoreLocationManager()
coreLocationManager?.locations = customerCoordinates
coreLocationManager?.startMonitoring()
coreLocationManager?.geoFenchCompletion = { (geoFenchType, customerName) in
print(geoFenchType)
print(customerName)
}
// Subscribe to CoreLocationManager's authorizationStatus updates
coreLocationManager?.authorizationStatusHandler = { status in
print(status.rawValue)
if status == .denied {
showAlert.toggle()
}
}
}
}.alert(isPresented: $showAlert) {
Alert(title: Text("Geofence Event"), message: Text("alertMessage"), dismissButton: .default(Text("OK")))
}
}
}
I am getting callback at authorizationStatus Handler but not getting on geoFenchCompletion, stuck from long long time