#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")
}
}
Ссылки, которые я видел, чтобы помочь реализовать фоновое местоположение при завершении работы приложения, следующие:
- https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/about_the_background_execution_sequence
- https://developer.apple.com/documentation/corelocation/monitoring_the_user_s_proximity_to_geographic_regions
- https://developer.apple.com/documentation/uikit/app_and_environment/responding_to_the_launch_of_your_app/about_the_app_launch_sequence
Комментарии:
1. Пожалуйста, уточните вашу конкретную проблему или предоставьте дополнительные сведения, чтобы выделить именно то, что вам нужно. Как написано в настоящее время, трудно точно сказать, о чем вы спрашиваете.
Ответ №1:
Попробуйте также вызвать createRegion
функцию внутри applicationWillTerminate(_ application: UIApplication)
. Регион будет создан, когда приложение будет завершено пользователем.
func applicationWillTerminate(_ application: UIApplication) {
createRegion(location: myLocation)
}