ios - CLLocationManager 区域监控 : Detect Arrival in Suspended State

标签 ios swift background cllocationmanager geofencing

我正在寻找一种方法来跟踪用户是否已到达一组指定的坐标附近。该功能需要在应用程序处于后台时(最好在 100 米内)工作。此外,为了节省电池电量,我最好不希望获得太多坐标读数(也许每 10 分钟一次读数,持续时间不超过几个小时)。

我尝试了几种方法来完成这项任务,但都无法获得预期的结果:

后台计时器:

我在(App.delegate)中添加了一个后台任务

func applicationDidEnterBackground(_ application: UIApplication)

其中执行了一个重复的Timer.scheduledTimer来获取坐标并处理

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

检测用户是否在范围内。如果在短期内应用此方法,则此方法有效,但仅在应用程序暂停之前有效,即大约 3 分钟。理想情况下,我不想如此频繁地获取坐标。

区域监控:

我已经初始化了 CLLocationManager,如下所示:

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

    locationManager.delegate = self
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.pausesLocationUpdatesAutomatically = false
    locationManager.activityType = .otherNavigation
    locationManager.requestAlwaysAuthorization()
}

LocationManager 在应用程序进入后台时启动:

func applicationDidEnterBackground(_ application: UIApplication) {
    self.monitorRegionAtLocation(center: CLLocationCoordinate2D(latitude: x, longitude: y), identifier: id)
    locationManager.startUpdatingLocation()
}

区域监控代码:

func monitorRegionAtLocation(center: CLLocationCoordinate2D, identifier: String ) {
    // Make sure the app is authorized.
    if CLLocationManager.authorizationStatus() == .authorizedAlways {
        // Make sure region monitoring is supported.
        if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
            // Register the region.
            let maxDistance = 200.0
            let region = CLCircularRegion(center: center,
                                          radius: maxDistance, identifier: identifier)
            region.notifyOnEntry = true
            region.notifyOnExit = false

            locationManager.startMonitoring(for: region)
        }
    }
}

并且我为 CLLocationManager 添加了一个 didEnterRegion 功能 block :

func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
    if let region = region as? CLCircularRegion {
        let identifier = region.identifier
        print("FOUND: " + identifier)
    }
}

该代码似乎可用于检测进入某个区域,但坐标不会在后台更新。

附加信息

  • 我启用了位置更新和后台获取的后台模式
  • 我在 Info.plist 中提供了“位置始终使用说明”和“使用时位置使用说明”的值
  • 应用程序设置显示对位置的“始终”权限

我相信必须有更好的方法在后台进行这些类型的检查,但我还没有发现任何在后台检测其他 Action 的方法。

我们将不胜感激关于此事的任何指示,如果您需要更多信息,请告诉我,我会尽力提供。

更新:

我已经按照以下评论的建议修改了使用区域监控的方法。

最佳答案

任何位置更新/监控都需要正确配置其位置管理器,以便它能够以最佳状态提供所需的位置更新。在进行后台位置更新时检查一些点很重要:

1。检查位置更新和后台获取的后台模式应该启用

2。勾选Info.plist中的'Location Always Usage Description'和'Location When in Use Usage Description'应该提供

3。检查您是否想在位置更新之间暂停 - 如果是,那么您需要提供事件类型,以便位置管理员可以确定为您暂停位置更新的最佳方式

4。检查您是否要应用距离过滤器 - 您希望用户(设备)移动一些最小量以便位置管理器发送更新的位置

5。检查您是否需要所需的精度 - 这可能会导致某些精度类型的功耗

在您的代码中,我可以看到位置管理器配置了一些参数,但缺少背景模式的精度和距离过滤器。

   locationManager.allowsBackgroundLocationUpdates = true
   locationManager.pausesLocationUpdatesAutomatically = false
   locationManager.activityType = .otherNavigation

此外,如果您在 Apple doc 中看到暂停位置更新属性它说:

For apps that have in-use authorization, a pause to location updates ends access to location changes until the app is launched again and able to restart those updates. If you do not wish location updates to stop entirely, consider disabling this property and changing location accuracy to kCLLocationAccuracyThreeKilometers when your app moves to the background. Doing so allows you to continue receiving location updates in a power-friendly manner.

从本质上讲,它告诉您如果您想要禁用暂停,那么您必须保持准确度级别 (kCLLocationAccuracyThreeKilometers)。我想您的方法中缺少这一点。

此外,您还可以检查 this link它实际上启动后台任务,然后在后台任务中启动位置管理器监控。 希望对您有所帮助。

关于ios - CLLocationManager 区域监控 : Detect Arrival in Suspended State,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46397999/

相关文章:

ios - func UIPageViewController didFinishAnimating 不工作

ios - 在 block 中调用时未发出 CLLocationManager 身份验证请求

java - Java 小程序中的背景图像

ios - 计时器给我随机数作为返回

ios - 从按钮添加照片库中的图像并在按钮上显示照片

swift - 为什么我的 swift 计时器一直在加速?

iphone - 在 iOS 4.3 中,当您按下主页按钮或按下开/关按钮时,我如何区分后台模式?

css - 如何在 Chrome 以外的浏览器中保持透明径向背景平滑?

ios - PHImageManager.requestImageForAsset 在 iOS swift 中返回低分辨率图像

iphone - toSharedViewController 不重用现有的 Controller