Merge master in to my branch with Geofence iOS

geofencing_wifi
Zohaib Kambrani 5 years ago
parent 67f4b4e167
commit b7088f70cd

@ -1 +1 @@
067d482a9455eae7d109c3ac5a36de46
3f3d14a0ae775b56806906c2cb14a1f0

@ -17,9 +17,8 @@ import GoogleMaps
HMGPlatformBridge.initialize(flutterViewController: mainViewController)
}
HMG_Geofence.initGeofencing()
if let _ = launchOptions?[.location] {
HMG_Geofence.initGeofencing()
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)

@ -120,3 +120,13 @@ extension UIView{
}
extension UIViewController{
func showAlert(withTitle: String, message: String){
let alert = UIAlertController(title: withTitle, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .destructive, handler: nil))
present(alert, animated: true) {
}
}
}

@ -6,6 +6,7 @@
//
import UIKit
import CoreLocation
class GeoZoneModel{
var geofenceId:Int = -1
@ -20,7 +21,26 @@ class GeoZoneModel{
var isCity:String?
func identifier() -> String{
return "\(geofenceId)_\(description)"
return "\(geofenceId)_hmg_geozone"
}
func message() -> String{
return description
}
func toRegion(locationManager:CLLocationManager) -> CLCircularRegion?{
if let rad = radius, let lat = latitude?.removeSpace(), let long = longitude?.removeSpace(),
let radius_d = Double("\(rad)"), let lat_d = Double(lat), let long_d = Double(long){
let coordinate = CLLocationCoordinate2D(latitude: lat_d, longitude: long_d)
let validatedRadius = min(radius_d, locationManager.maximumRegionMonitoringDistance)
let region = CLCircularRegion(center: coordinate, radius: validatedRadius, identifier: identifier())
region.notifyOnExit = true
region.notifyOnEntry = true
return region
}
return nil
}
class func from(json:[String:Any]) -> GeoZoneModel{

@ -19,11 +19,29 @@ func dictionaryArray(from:String) -> [[String:Any]]{
}
func showNotification(identifier:String? = nil, title:String?, subtitle:String?, message:String?, sound:UNNotificationSound = UNNotificationSound.default){
let notificationContent = UNMutableNotificationContent()
if identifier != nil { notificationContent.categoryIdentifier = identifier! }
if title != nil { notificationContent.title = title! }
if subtitle != nil { notificationContent.body = message! }
if message != nil { notificationContent.subtitle = subtitle! }
notificationContent.sound = UNNotificationSound.default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
let request = UNNotificationRequest(identifier: "\(Date().timeIntervalSinceNow)", content: notificationContent, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error: \(error)")
}
}
}
func httpPostRequest(urlString:String, jsonBody:[String:Any], completion:((Bool,[String:Any]?)->Void)?){
let json: [String: Any] = jsonBody
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: urlString)!
var request = URLRequest(url: url)
@ -31,7 +49,7 @@ func httpPostRequest(urlString:String, jsonBody:[String:Any], completion:((Bool,
request.addValue("*/*", forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
@ -49,7 +67,7 @@ func httpPostRequest(urlString:String, jsonBody:[String:Any], completion:((Bool,
}
}
task.resume()
}

@ -38,7 +38,9 @@ class HMG_Geofence:NSObject{
private static var shared_:HMG_Geofence?
class func shared() -> HMG_Geofence{
assert(shared_ != nil, "HMG_Geofence is not initialized, call initGeofencing() function first.")
if HMG_Geofence.shared_ == nil{
HMG_Geofence.initGeofencing()
}
return shared_!
}
@ -48,28 +50,33 @@ class HMG_Geofence:NSObject{
}
func register(geoZones:[GeoZoneModel]){
self.geoZones = geoZones
// self.geoZones?.forEach({ (zone) in
// startMonitoring(zone: zone)
// })
let z = geoZones[14]
if monitoredRegions().filter { $0.identifier == z.identifier()}.isEmpty{
startMonitoring(zone: z)
}
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(zone: GeoZoneModel) {
func startMonitoring(region: CLCircularRegion) {
if !CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
return
}
@ -82,13 +89,9 @@ extension HMG_Geofence : CLLocationManagerDelegate{
debugPrint(message)
}
if let fenceRegion = region(with: zone){
locationManager.startMonitoring(for: fenceRegion)
locationManager.requestState(for: fenceRegion)
debugPrint("Monitering region: \(fenceRegion.center) | \(fenceRegion.identifier)")
}else{
debugPrint("Invalid region: \(zone.latitude ?? ""),\(zone.longitude ?? ""),r\(zone.radius ?? 0) | \(zone.identifier())")
}
locationManager.startMonitoring(for: region)
locationManager.requestState(for: region)
debugPrint("Starts monitering region: \(region)")
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
@ -120,70 +123,58 @@ extension HMG_Geofence : CLLocationManagerDelegate{
extension HMG_Geofence{
func handleEvent(for region: CLRegion!, transition:Transition, location:CLLocation?) {
if let zone = geoZone(by: region.identifier){
notifyUser(forZone: zone, transition: transition, location: locationManager.location)
notifyServer(forZone: zone, transition: transition, location: locationManager.location)
}
}
func region(with geoZone: GeoZoneModel) -> CLCircularRegion? {
if !geoZone.identifier().isEmpty,
let radius = geoZone.radius, let lat = geoZone.latitude?.removeSpace(), let long = geoZone.longitude?.removeSpace(),
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
notifyUser(forRegion: region, transition: transition, location: locationManager.location)
notifyServer(forRegion: region, transition: transition, location: locationManager.location)
}
func geoZone(by id: String) -> GeoZoneModel? {
return geoZones?.first(where: { $0.identifier() == id})
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(forZone:GeoZoneModel, transition:Transition, location:CLLocation?){
if UIApplication.shared.applicationState == .active {
mainViewController.showAlert(withTitle: transition.name(), message: forZone.identifier())
} else {
let notificationContent = UNMutableNotificationContent()
notificationContent.title = transition.name()
notificationContent.body = forZone.identifier()
notificationContent.sound = UNNotificationSound.default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
let request = UNNotificationRequest(identifier: "\(Date().timeIntervalSinceNow)",
content: notificationContent,
trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Error: \(error)")
}
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(forZone: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 let body = params as? [String : Any]{
httpPostRequest(urlString: url, jsonBody: body){ (status,json) in
if let json_ = json , status{
}else{
}
}
}
}
func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){
showNotification(title: "Notifying server..." , subtitle: forRegion.identifier, message: "")
if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){
let body:[String:Any] = ["PointsID":idInt,"GeoType":transition.rawValue,"PatientID":"1231755"]
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 ")
// }
// }
// }
// }
// }
// }
}

File diff suppressed because one or more lines are too long

@ -12,10 +12,10 @@ const EXA_CART_API_BASE_URL = 'https://mdlaboratories.com/exacartapi';
const PACKAGES_CATEGORIES = '/api/categories';
const PACKAGES_PRODUCTS = '/api/products';
const BASE_URL = 'https://uat.hmgwebservices.com/';
// const BASE_URL = 'https://uat.hmgwebservices.com/';
const PING_SERVICE = 'Services/Weather.svc/REST/CheckConnectivity';
// const BASE_URL = 'https://hmgwebservices.com/';
const BASE_URL = 'https://hmgwebservices.com/';
const GET_PROJECT = 'Services/Lists.svc/REST/GetProject';
///Geofencing

@ -20,6 +20,8 @@ class GeofencingServices extends BaseService {
Future<List<GeoZonesResponseModel>> getAllGeoZones(GeoZonesRequestModel request) async {
hasError = false;
var _zonesJsonString;
await baseAppClient.post(GET_GEO_ZONES, onSuccess: (dynamic response, int statusCode) {
var zones = response['GeoF_PointsList'];
zones.forEach((json) {
@ -28,13 +30,16 @@ class GeofencingServices extends BaseService {
if (kDebugMode || testZones) addTestingGeoZones(zones);
var zonesJsonString = json.encode(zones);
AppSharedPreferences().setString(HMG_GEOFENCES, zonesJsonString);
debugPrint("GEO ZONES saved to AppPreferences with key '$HMG_GEOFENCES'");
_zonesJsonString = json.encode(zones);
}, onFailure: (String error, int statusCode) {
hasError = true;
return Future.error(error);
}, body: request.toFlatMap());
AppSharedPreferences pref = AppSharedPreferences();
await pref.setString(HMG_GEOFENCES, _zonesJsonString);
debugPrint("GEO ZONES saved to AppPreferences with key '$HMG_GEOFENCES'");
return geoZones;
}
@ -51,8 +56,10 @@ class GeofencingServices extends BaseService {
}
addTestingGeoZones(List zones) {
zones.add({"GEOF_ID": 100, "zkH": "", "Latitude": "24.691136", "Longitude": "46.650116", "Radius": 100, "Type": 1});
zones.add({"GEOF_ID": 101, "csO": "", "Latitude": "24.7087913", "Longitude": "46.6656461", "Radius": 100, "Type": 1});
zones.add({"GEOF_ID": 102, "msH": "", "Latitude": "24.777577", "Longitude": "46.652675", "Radius": 100, "Type": 1});
zones.add({"GEOF_ID": -1, "Description": "ZiK Home", "Latitude": "24.691136", "Longitude": "46.650116", "Radius": 100, "Type": 1});
zones.add({"GEOF_ID": -2, "Description": "CS Office", "Latitude": "24.7087913", "Longitude": "46.6656461", "Radius": 100, "Type": 1});
zones.add({"GEOF_ID": -3, "Description": "Mahmoud Shrouf Home", "Latitude": "24.777577", "Longitude": "46.652675", "Radius": 100, "Type": 1});
zones.add({"GEOF_ID": -4, "Description": "Panorama Mall", "Latitude": "24.692453", "Longitude": "46.669168", "Radius": 450, "Type": 1});
zones.add({"GEOF_ID": -5, "Description": "Saudi Architects Crossing", "Latitude": "24.698375", "Longitude": "46.668567", "Radius": 140, "Type": 1});
}
}

Loading…
Cancel
Save