You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HMG_Patient_App/ios/Runner/Helper/HMG_Geofence.swift

189 lines
7.1 KiB
Swift

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

//
// 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
func name() -> String{
return self.rawValue == 1 ? "Enter" : "Exit"
}
}
class HMG_Geofence:NSObject{
var geoZones:[GeoZoneModel]?
var locationManager:CLLocationManager!{
didSet{
// https://developer.apple.com/documentation/corelocation/cllocationmanager/1423531-startmonitoringsignificantlocati
locationManager.allowsBackgroundLocationUpdates = true
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.activityType = .other
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
// locationManager.distanceFilter = 500
// locationManager.startMonitoringSignificantLocationChanges()
}
}
private static var shared_:HMG_Geofence?
class func shared() -> HMG_Geofence{
if HMG_Geofence.shared_ == nil{
HMG_Geofence.initGeofencing()
}
return shared_!
}
class func initGeofencing(){
shared_ = HMG_Geofence()
shared_?.locationManager = CLLocationManager()
}
func register(geoZones:[GeoZoneModel]){
self.geoZones = geoZones
let monitoredRegions_ = monitoredRegions()
self.geoZones?.forEach({ (zone) in
if let region = zone.toRegion(locationManager: locationManager){
if let already = monitoredRegions_.first(where: {$0.identifier == zone.identifier()}){
debugPrint("Already monitering region: \(already)")
}else{
startMonitoring(region: region)
}
}else{
debugPrint("Invalid region: \(zone.latitude ?? "invalid_latitude"),\(zone.longitude ?? "invalid_longitude"),r\(zone.radius ?? 0) | \(zone.identifier())")
}
})
}
func monitoredRegions() -> Set<CLRegion>{
return locationManager.monitoredRegions
}
}
// CLLocationManager Delegates
extension HMG_Geofence : CLLocationManagerDelegate{
func startMonitoring(region: CLCircularRegion) {
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)
}
locationManager.startMonitoring(for: region)
locationManager.requestState(for: region)
debugPrint("Starts monitering region: \(region)")
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
debugPrint("didEnterRegion: \(region)")
if region is CLCircularRegion {
handleEvent(for: region,transition: .entry, location: manager.location)
}
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
debugPrint("didExitRegion: \(region)")
if region is CLCircularRegion {
handleEvent(for: region,transition: .exit, location: manager.location)
}
}
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
debugPrint("didDetermineState: \(state)")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
debugPrint("didUpdateLocations: \(locations)")
}
}
// Helpers
extension HMG_Geofence{
func handleEvent(for region: CLRegion!, transition:Transition, location:CLLocation?) {
notifyUser(forRegion: region, transition: transition, location: locationManager.location)
notifyServer(forRegion: region, transition: transition, location: locationManager.location)
}
func geoZone(by id: String) -> GeoZoneModel? {
var zone:GeoZoneModel? = nil
if let zones_ = geoZones{
zone = zones_.first(where: { $0.identifier() == id})
}else{
// let jsonArray = UserDefaults.standard.string(forKey: "hmg-geo-fences")
}
return zone
}
func notifyUser(forRegion:CLRegion, transition:Transition, location:CLLocation?){
if let zone = geoZone(by: forRegion.identifier){
if UIApplication.shared.applicationState == .active {
mainViewController.showAlert(withTitle: transition.name(), message: zone.message())
}else{
}
}
}
func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){
showNotification(title: "Notifying server..." , subtitle: forRegion.identifier, message: "")
if let userProfileJson = UserDefaults.standard.string(forKey: "user-profile"),
let userProfile = dictionary(from: userProfileJson), let patientId = userProfile["PatientID"] as? String{
if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){
let body:[String:Any] = [
"PointsID":idInt,
"GeoType":transition.rawValue,
"PatientID":patientId
]
let url = "https://hmgwebservices.com/Services/Patients.svc/REST/GeoF_InsertPatientFileInfo"
httpPostRequest(urlString: url, jsonBody: body){ (status,json) in
showNotification(title: transition.name(), subtitle: forRegion.identifier, message: status ? "Success: notified to server ✔️" : "Failed to notified server ✖️")
}
}
}
}
// func notifyServer(forRegion:GeoZoneModel, transition:Transition, location:CLLocation?){
// flutterMethodChannel?.invokeMethod("getLogGeofenceFullUrl", arguments: nil){ fullUrlString in
// if let url = fullUrlString as? String{
// flutterMethodChannel?.invokeMethod("getDefaultHttpParameters", arguments: nil){ params in
// if var body = params as? [String : Any]{
// body.updateValue(forZone.geofenceId, forKey: "PointsID")
// body.updateValue(transition.rawValue, forKey: "GeoType")
// httpPostRequest(urlString: url, jsonBody: body){ (status,json) in
// showNotification(title: transition.name(), subtitle: forZone.identifier(), message: status ? "Success: sent to server " : "Failed: sent to server ")
// }
// }
// }
// }
// }
// }
}