【发布时间】:2018-03-05 23:56:43
【问题描述】:
我正在寻找一种方法来跟踪用户是否已到达指定的一组坐标附近。该功能需要在应用程序在后台运行时(最好在 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 功能块:
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
if let region = region as? CLCircularRegion {
let identifier = region.identifier
print("FOUND: " + identifier)
}
}
该代码似乎可用于检测进入某个区域,但是在后台时坐标不会更新。
其他信息
- 我启用了位置更新和后台获取的后台模式
- 我在 Info.plist 中提供了“位置始终使用说明”和“位置使用时使用说明”的值
- 应用设置显示针对位置的“始终”权限
我相信必须有更好的方法在后台进行此类检查,但我还没有发现任何检测后台其他动作的方法。
我们将不胜感激任何关于此事的指导,如果您需要更多信息,请告诉我,我会尽我所能。
更新:
我已按照以下 cmets 的建议修改了方法以使用区域监控。
【问题讨论】:
-
谢谢@Paulw11。我已经修改了方法和问题以更好地适应区域监控,但是我无法从后台获取坐标。
-
你在哪里初始化你的
locationManager?是局部变量还是类属性? -
您想在被杀死或暂停模式下获取坐标吗?我最近完成了一个关于地理围栏的项目,发现它只有在应用程序处于后台时才有效,明天我会用我所做的事情更新你。如果我对你有帮助会很高兴。 :)
-
@TarasChernyshenko 我目前在 AppDelegate 中对其进行了初始化。最初设计 Background Timer 解决方案时,我将其包含在一个单独的 BackgroundWorker 类中,该类似乎可以工作,直到应用程序在 3 分钟后暂停。
标签: ios swift background cllocationmanager geofencing