CLLocationManager区域监控:在暂停状态下检测到达

问题描述:

我正在寻找一种方法,可以跟踪用户到达指定坐标集附近的情况。该功能需要在应用程序处于后台时工作(最好在100米以内)。另外,为了保存电池,我最好不要想太多的坐标读数(也许每10分钟读一次,时间不超过几个小时)。CLLocationManager区域监控:在暂停状态下检测到达

有一对夫妇的,我试图完成这项任务的方式,但一直未能取得理想的结果:

背景定时器:

我在添加一个后台任务( 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 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) 
     } 
    } 
} 

我加入didEnterRegion功能块CLLocationManager:

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

的代码出现到用于检测进入的区域工作,然而,坐标不更新,而在背景中。

其他信息

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

我相信在后台运行这些检查应该有更好的方法,但我还没有发现任何检测背景中其他运动的方法。

任何方向在这个问题上将不胜感激,如果你需要任何更多的信息,请让我知道,我会尽我所能。

UPDATE:

我已经修改了以下的下面的评论使用地区监控的意见的做法。

+1

[使用区域监控](https://developer.apple.com/documentation/corelocation/monitoring_the_user_s_proximity_to_geographic_regions) – Paulw11

+0

Thanks @ Paulw11。我已经修改了方法和问题以更好地适合区域监测,但是我一直无法从后台获得坐标。 –

+0

你在哪里初始化你的'locationManager'?它是局部变量还是类属性? –

任何位置更新/监控都要求其位置管理器进行正确配置,以便它能够最好地提供所需的位置更新。

1.位置更新和背景的了解后台模式获取应使

2.检查“位置始终使用情况说明”和“位置时:做背景位置更新时检查一些点是很重要的应提供Info.plist中的“使用说明中的使用说明”

暂停位置更新

4.检查是否要应用距离滤波器的 - 你想用户(设备)将一些最低金额为外景经理如果你想所需accuracy-发送更新的位置

5.检查这可能会导致某些精度类型的功耗

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

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

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

对于有使用授权的应用程序,暂停向位置更新 结束访问位置的变化,直到应用程序再次启动并且 能够重新启动这些更新。如果您不希望位置更新为 完全停止,请考虑禁用此媒体资源并将位置更改为kCLLocationAccuracyThreeKilometers,当您的应用移动到 时,背景为 。这样做可让您继续以电源友好的方式接收位置 更新。

本质上它告诉如果你想禁用暂停,那么你必须保持精度等级(kCLLocationAccuracyThreeKilometers)。我猜想你的方法中缺少了这一点。

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

+0

感谢您的反馈。我已经在周末进行了几次区域监控的测试,并能够从后台建立一些didEnterRegion触发器。使用locationManager.startMonitoringSignificantLocationChanges()时,我不相信精度或距离过滤器是必需的,我最终选择使用locationManager.startMonitoringSignificantLocationChanges()。 [此资源](https://www.raywenderlich.com/136165/core-location-geofencing-tutorial)是深入了解我的问题的非常有用的指南,但您的观点也很重要。 –

+0

好的。大。那么实际问题是什么? – manismku

问题说:“CLLocationManager区域监视:检测到达背景”。这是非常可能的,但是在被杀之后检测任何东西是不可能的(从iOS 7开始)。

无论何时用户向上轻扫应用程序切换器,iOS都会采用该应用程序,因为用户不希望应用程序在后台运行,因此所有回调都会停止。

This answer,this answerthis answer也说同样的事情。然而Apple doc有点令人困惑。

我个人的观察是,应用程序甚至在杀死模式下被调用,但很少。

关于获取位置,只要调用geofencing的委托方法,您就可以轻松获取位置。

而您的需求并不需要背景模式。

不幸的是(对于iOS用户来说,幸运的是他们节省了电池),我们真的没有办法在应用程序被杀后1小时内获得位置。

+0

感谢您的评论。也许我在说明'背景'时会混淆这个问题,但我的意思是在暂停状态(我已经在标题中解决了这个问题)。看起来解决方案将工作大约3分钟,这可能是后台状态,但之后停止运行,我怀疑这是由于应用程序进入暂停状态。该应用程序仍然在应用程序切换器,并没有被刷卡杀死它(只是坐在后台)。 –