我在我的 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