Start region monitoring right after the app goes to terminated state

530 Views Asked by At

I'm using region monitoring in my iOS app to get location updates every time when my app is terminated and, after my app is closed, the service starts 20-30 minutes later and I want to start the service right after the app is closed. How I do that and what I have to do to do that? Any help would be appreciated, thanks. Here's my code of AppDelegate.swift to understand better the problem to this question.

//

//  AppDelegate.swift

//  OnDICA

//

//  Created by DICA Information Systems on 16/06/2021.

//



import UIKit

import FBSDKCoreKit

import UserNotifications

import CoreLocation



@main

class AppDelegate: UIResponder, UIApplicationDelegate {



    var locationManager:CLLocationManager? = CLLocationManager()

    var myLocation:CLLocation?



    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        Thread.sleep(forTimeInterval: 0.60)

        // Override point for customization after application launch.

        

        

        ApplicationDelegate.shared.application(

            application,

            didFinishLaunchingWithOptions:

            launchOptions

        )

        

        registerForPushNotifications()

        configureUserNotifications()

        print("a testar o modo terminated")

        

        if launchOptions?[UIApplication.LaunchOptionsKey.location] != nil {

            if locationManager == nil {

                locationManager = CLLocationManager()

                locationManager?.delegate = self

                locationManager?.distanceFilter = kCLDistanceFilterNone

                locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation

                locationManager?.activityType = CLActivityType.otherNavigation

                locationManager?.allowsBackgroundLocationUpdates = true

                locationManager?.pausesLocationUpdatesAutomatically = false

                locationManager?.startMonitoringSignificantLocationChanges()

                locationManager?.startUpdatingLocation()

            } else {

                locationManager = nil

                locationManager = CLLocationManager()

                locationManager?.delegate = self

                locationManager?.distanceFilter = kCLDistanceFilterNone

                locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation

                locationManager?.activityType = CLActivityType.otherNavigation

                locationManager?.allowsBackgroundLocationUpdates = true

                locationManager?.pausesLocationUpdatesAutomatically = false

                locationManager?.startMonitoringSignificantLocationChanges()

                locationManager?.startUpdatingLocation()

            }

        } else {

            locationManager?.delegate = self

            locationManager?.distanceFilter = kCLDistanceFilterNone

            locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation

            locationManager?.activityType = CLActivityType.otherNavigation

            locationManager?.pausesLocationUpdatesAutomatically = false

            locationManager?.allowsBackgroundLocationUpdates = true

            

            if CLLocationManager.authorizationStatus() == .authorizedAlways {

                locationManager?.startUpdatingLocation()

                locationManager?.startMonitoringSignificantLocationChanges()

            }

        }

        return true

    }

    

    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {

        if launchOptions != nil {

           // if launchOptions?.contains(location)

            

        } else {

            print("sem conteúdo")

        }

        print("a testar o relaunching")

        return true

    }

    

    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {

        return ApplicationDelegate.shared.application(

            app,

            open: url,

            options: options

        )



    }

    

    func applicationDidEnterBackground(_ application: UIApplication) {

        while true {

            createRegion(location: myLocation)

        }

        print("applicationDidEnterBackground")

        

        return

    }

    

    func applicationDidBecomeActive(_ application: UIApplication) {

        while true {

            createRegion(location: myLocation)

        }

        print("applicationDidEnterBackground")

        

        return

    }



    // MARK: UISceneSession Lifecycle



    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {

        // Called when a new scene session is being created.

        // Use this method to select a configuration to create the new scene with.

        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)

    }



    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {

        // Called when the user discards a scene session.

        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.

        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.

    }

    



    

//    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

//        if let launchOptions = launchOptions,

//            let isLocationKey = launchOptions[UIApplication.LaunchOptionsKey.location] as? Bool,

//            isLocationKey {

//            restartServices()

//

//        }

//        return true

 //   }



    func registerForPushNotifications() {

        UNUserNotificationCenter.current()

          .requestAuthorization(

            options: [.alert, .sound, .badge]) { [weak self] granted, _ in

            print("Permission granted: \(granted)")

            guard granted else { return }

            self?.getNotificationSettings()

          }

    }

    

    func getNotificationSettings() {

      UNUserNotificationCenter.current().getNotificationSettings { settings in

        print("Notification settings: \(settings)")

          guard settings.authorizationStatus == .authorized else { return }

          DispatchQueue.main.async {

            UIApplication.shared.registerForRemoteNotifications()

          }

      }

        

    }



    private func configureUserNotifications() {

      UNUserNotificationCenter.current().delegate = self        //permite abrir em foreground

    }

    

    func createRegion(location:CLLocation?) {

        print("criação da região")

        guard let location = location else {

            return

        }

        if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {

            print("Available Region Monitoring/Geofencing")

            let coordinate = CLLocationCoordinate2DMake((location.coordinate.latitude), (location.coordinate.longitude))

            let regionRadius = 1.0

            

            let region = CLCircularRegion(center: CLLocationCoordinate2D(

                latitude: location.coordinate.latitude,

                longitude: location.coordinate.longitude),

                                          radius: regionRadius,

                                          identifier: "aabb")

            

            region.notifyOnExit = true

        }

    }



}



extension AppDelegate: UNUserNotificationCenterDelegate {

  func userNotificationCenter(

    _ center: UNUserNotificationCenter,

    willPresent notification: UNNotification,

    withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void

  ) {

    completionHandler(.banner)

  }

}



extension AppDelegate: CLLocationManagerDelegate {

    

    //MARK:- LocationManager Delegates

    

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {

        if status == .authorizedAlways || status == .authorizedWhenInUse {

            manager.startUpdatingLocation()

        }
    }

    

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        let location = locations.last

        

        print("Precisão hoizontal: \(location?.horizontalAccuracy)")

               

        if let idClient = UserDefaults.standard.string(forKey: "userId") {

            let service = Notifications()

              service.startLocationUpdates()

        }

             

        print("precisão outra da localização")

        self.createRegion(location: location)

        

    }

    

    func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {

        print("didEnterRegion")

        manager.startMonitoringSignificantLocationChanges()

        manager.startUpdatingLocation()

    }

    

    func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {

        manager.startMonitoringSignificantLocationChanges()

        manager.startUpdatingLocation()

    }

    

    func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) {

        print("error monitoring")

    }

    

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

        print("error monitoring 1")

    }

    

    func locationManager(_ manager: CLLocationManager, didVisit visit: CLVisit) {

        print("visitou certo sítio")

    }

}

The links that I saw to help to implement the background location when the app is terminated are the following:

1

There are 1 best solutions below

0
saber On

Try also calling the createRegion function inside applicationWillTerminate(_ application: UIApplication) . The region would be created when the app gets terminated by the user.

func applicationWillTerminate(_ application: UIApplication) {
     createRegion(location: myLocation)
}