Запуск мониторинга региона сразу после перехода приложения в завершенное состояние

#ios #swift #background #geofencing #region-monitoring

#iOS #swift #предыстория #геозона #мониторинг региона

Вопрос:

Я использую мониторинг региона в своем приложении для iOS, чтобы получать обновления местоположения каждый раз, когда мое приложение завершается, и после закрытия моего приложения служба запускается через 20-30 минут, и я хочу запустить службу сразу после закрытия приложения. Как я это делаю и что мне нужно для этого сделать? Любая помощь будет оценена, спасибо. Вот мой код AppDelegate.swift, чтобы лучше понять проблему этого вопроса.

 //

//  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")

    }

}
 

Ссылки, которые я видел, чтобы помочь реализовать фоновое местоположение при завершении работы приложения, следующие:

Комментарии:

1. Пожалуйста, уточните вашу конкретную проблему или предоставьте дополнительные сведения, чтобы выделить именно то, что вам нужно. Как написано в настоящее время, трудно точно сказать, о чем вы спрашиваете.

Ответ №1:

Попробуйте также вызвать createRegion функцию внутри applicationWillTerminate(_ application: UIApplication) . Регион будет создан, когда приложение будет завершено пользователем.

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