简体   繁体   English

在应用程序终止时获取用户的位置

[英]Getting the user's location when app is terminated

I'm currently working on an app and am encountering a problem. 我目前正在开发应用程序并遇到问题。 The purpose of my app is to see when someone leaves work. 我的应用程序的目的是看看有人离开工作。 For that to work 100% of the time the app should be able to get the user's location while the app is open, in the background or terminated (killed). 为了使其在100%的时间内工作,应用程序应该能够在应用程序打开时,在后台或终止(被杀死)时获取用户的位置。 My understanding is that you have to use the significant location change functionality for this. 我的理解是你必须使用重要的位置更改功能。 However, it's not working as expected. 但是,它没有按预期工作。

AppDelegate: AppDelegate中:

    //handle location changes when app is terminated and waken up by the OS
    if launchOptions?[UIApplicationLaunchOptionsKey.location] != nil {
        print("Restarted app due to a location update")
        request = Locator.subscribeSignificantLocations(onUpdate: { newLoc in
            let db: FirebaseDB = FirebaseDB.shared
            db.postCoordinates(coordinates: CLLocation(latitude: 9.99, longitude: 9.99))
            print("new loc found -> \(newLoc)")
        }, onFail: {(err, lastLoc) in
            print("failed to get loc, -> \(err)")
        })
        //send new post to DB
    }

    //subscribeSignificantLocations -> power efficient
        request = Locator.subscribeSignificantLocations(onUpdate: { newLoc in
            print("new loc found -> \(newLoc)")
        }, onFail: {(err, lastLoc) in
            print("failed to get new loc, -> \(err)")
        })

Everything works except for getting the location when the app is terminated... 一切正常,除了在应用程序终止时获取位置...

Thanks in advance! 提前致谢!

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 ) 注意:我正在进行地理围栏,我需要在用户离开某个区域时通知/调用API

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. 其次,即使在应用程序终止后,我们也需要使用startMonitoringSignificantLocationChanges()进行位置更新。

        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. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM