// // HMG_Geofence.swift // Runner // // Created by ZiKambrani on 13/12/2020. // import UIKit import CoreLocation fileprivate var df = DateFormatter() fileprivate var transition = "" enum Transition:Int { case entry = 1 case exit = 2 } class HMG_Geofence:NSObject{ var geoZones:[GeoZoneModel]? var locationManager = CLLocationManager() func initLocationManager(){ locationManager.delegate = self locationManager.allowsBackgroundLocationUpdates = true locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters locationManager.activityType = .other locationManager.requestAlwaysAuthorization() } func register(geoZones:[GeoZoneModel]){ self.geoZones = geoZones self.geoZones?.forEach({ (zone) in startMonitoring(zone: zone) }) } func wakeup(){ initLocationManager() } func monitoredRegions() -> Set{ return locationManager.monitoredRegions } } // CLLocationManager Delegates extension HMG_Geofence : CLLocationManagerDelegate{ func startMonitoring(zone: GeoZoneModel) { if !CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) { return } if CLLocationManager.authorizationStatus() != .authorizedAlways { let message = """ Your geotification is saved but will only be activated once you grant HMG permission to access the device location. """ debugPrint(message) } if let fenceRegion = region(with: zone){ locationManager.startMonitoring(for: fenceRegion) locationManager.requestState(for: fenceRegion) } } func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) { if region is CLCircularRegion { handleEvent(for: region,transition: .entry, location: manager.location) } } func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) { if region is CLCircularRegion { handleEvent(for: region,transition: .exit, location: manager.location) } } } // Helpers extension HMG_Geofence{ func handleEvent(for region: CLRegion!, transition:Transition, location:CLLocation?) { if let zone = geoZone(by: region.identifier){ notifyUser(forZone: zone, transiotion: transition, location: locationManager.location) notifyServer(forZone: zone, transiotion: transition, location: locationManager.location) } } func region(with geoZone: GeoZoneModel) -> CLCircularRegion? { if !geoZone.identifier().isEmpty, let radius = geoZone.radius, let lat = geoZone.latitude, let long = geoZone.longitude, let radius_d = Double("\(radius)"), let lat_d = Double(lat), let long_d = Double(long){ let coordinate = CLLocationCoordinate2D(latitude: lat_d, longitude: long_d) let region = CLCircularRegion(center: coordinate, radius: radius_d, identifier: geoZone.identifier()) region.notifyOnEntry = true region.notifyOnExit = true return region } return nil } func geoZone(by id: String) -> GeoZoneModel? { return geoZones?.first(where: { $0.identifier() == id}) } func notifyUser(forZone:GeoZoneModel, transiotion:Transition, location:CLLocation?){ } func notifyServer(forZone:GeoZoneModel, transiotion:Transition, location:CLLocation?){ flutterMethodChannel?.invokeMethod("getLogGeofenceFullUrl", arguments: nil){ fullUrlString in if let url = fullUrlString as? String{ let body:[String : Any?] = [ "PointsID":forZone.geofenceId, "GeoType":transiotion.rawValue, "PatientID":"1231755", "ZipCode": "966", "VersionID": 5.6, "Channel": 3, "LanguageID": UserDefaults.standard.string(forKey: "language") ?? "ar", "IPAdress": "10.20.10.20", "generalid": "Cs2020@2016$2958", "PatientOutSA": 0, "isDentalAllowedBackend": false, "TokenID": "27v/qqXC/UGS2bgJfRBHYw==", "DeviceTypeID": 2 ] httpPostRequest(urlString: url, jsonBody: body){ (status,json) in if let json_ = json , status{ }else{ } } } } } }