After hours of searching and reading for the solution, I found a working solution for me. (NOTE: I am working on geofencing where I need to notify/call API the user when he leaves certain area)
The first and most important step is to have "always" authorization by the user for location access.
Second, we need to use startMonitoringSignificantLocationChanges()
for location update even after the app termination.
locationManager.requestAlwaysAuthorization()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.allowsBackgroundLocationUpdates = true
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges() //THIS IS WHERE THE MAGIC HAPPENS
Below is the code for getting the local notifications for location update.
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {
var window: UIWindow?
let locationManager = CLLocationManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
locationManager.requestAlwaysAuthorization()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.allowsBackgroundLocationUpdates = true
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
application.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert, .badge], categories: nil))
UIApplication.shared.cancelAllLocalNotifications()
return true
}
func alertUserOnLeaving(region:CLRegion){
if UIApplication.shared.applicationState == .active {
let alert = UIAlertController(title: "Alert Title", message: "Alert Message", style = .Alert
window?.rootViewController?.present(alert, animated: true, completion: nil)
}
else{
let notification = UILocalNotification()
notification.alertBody = "You forgot to checkout"
notification.soundName = "Default"
UIApplication.shared.presentLocalNotificationNow(notification)
}
}
func alertUserOnArrival(region:CLRegion){
if UIApplication.shared.applicationState == .active {
let alert = UIAlertController(title: "Alert Title", message: "Alert Message", style = .Alert
window?.rootViewController?.present(alert, animated: true, completion: nil)
}
else{
let notification = UILocalNotification()
notification.alertBody = "Welcome Please checkin"
notification.soundName = "Default"
UIApplication.shared.presentLocalNotificationNow(notification)
}
}
func setUpGeofenceForJob() {
let geofenceRegionCenter = CLLocationCoordinate2DMake(-33.7513580322265, 151.242416381836)
let geofenceRegion = CLCircularRegion(center: geofenceRegionCenter, radius: 100, identifier: "GeoFence")
geofenceRegion.notifyOnExit = true
geofenceRegion.notifyOnEntry = true
self.locationManager.startMonitoring(for: geofenceRegion)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if (status == CLAuthorizationStatus.authorizedAlways) {
self.setUpGeofenceForJob()
}
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
alertUserOnArrival(region: region)
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
alertUserOnLeaving(region: region)
}
Hope it helps.