【问题标题】:Location Manager didExitRegion not being called位置管理器 didExitRegion 未被调用
【发布时间】:2016-07-28 22:13:58
【问题描述】:

我已经设置了委托,创建了一个区域,并且我已经阅读了所有文档。每次用户的位置发生变化并且在指定区域之外时,都不会调用locationManager(manager: CLLocationManager, didExitRegion region: CLRegion)。我见过它被调用一次,然后它就停止了。我花了很多时间试图弄清楚发生了什么。

快速概览我在做什么:

当应用程序启动时,我调用locationManager.startUpdatingLocation(),然后调用代理locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]),我向服务器快速请求一些我需要的信息,创建一个CLCircularRegion,然后继续调用locationManager.stopUpdatingLocation()。在这种方法中,我调用了我的startMonitoringForRegion(_:)

可能是因为每次我创建一个新区域时它都使用相同的标识符? Apple 的文档说可以使用相同的标识符,因为它将替换前一个标识符,但我想知道这是否导致代表不调用 didExitRegion

我的代码如下。谢谢你。

  func configureLocation() {

    if CLLocationManager.locationServicesEnabled() {

        locationManager.delegate = self

        locationManager.requestAlwaysAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.allowsBackgroundLocationUpdates = false
        locationManager.pausesLocationUpdatesAutomatically = true

        // Distance filter to update location
        //locationManager.distanceFilter = 10.0

        // Begin updating user location
        locationManager.startUpdatingLocation()

    } else {

        let title = "Location disabled"
        let message = "To enable location services go to Settings > Privacy > Location Services"
        self.locationServicesAlertMessage(title, message: message)
    }
}


func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    print("didUpdateCalled")
    /*
    if UIApplication.sharedApplication().applicationState == .Active {
        print("ACTIVE UPDATE: location")
    } else if UIApplication.sharedApplication().applicationState == .Background {
        print("BACKGROUND UPDATE: location")
    }
    */

    if firstLocationUpdate {
        let center = CLLocationCoordinate2D(latitude: (manager.location?.coordinate.latitude)!, longitude: (manager.location?.coordinate.longitude)!)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpanMake(0.01, 0.01))

        self.mapView.setRegion(region, animated: true)

        self.firstLocationUpdate = false
    }


    // If the user is travelling less than 5 mph, update location
    if manager.location?.speed <= 3.5 {

        self.updateLongAndLat(manager.location!) { (lat, long) in

            print("LAT: \(lat)")
            print("LONG: \(long)")
            if lat != nil && long != nil {
                let center = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
                let monitoredRegion = CLCircularRegion(center: center, radius: 10.0, identifier: "UserRegion")
                monitoredRegion.notifyOnEntry = false
                self.locationManager.startMonitoringForRegion(monitoredRegion)
                self.locationManager.stopUpdatingLocation()
            }
        }
    }
}

func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) {
    print("EXITED REGION")

    print("Identifier: \(region.identifier)")
    if manager.location?.speed <= 3.5 {
        self.updateLongAndLat(manager.location!, completion: { (lat, long) in
            if lat != nil && long != nil {
                let center = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
                let monitoredRegion = CLCircularRegion(center: center, radius: 10.0, identifier: "UserRegion")
                self.locationManager.startMonitoringForRegion(monitoredRegion)
            }
        })
    }
}

【问题讨论】:

  • 遇到了同样的问题。让我发疯,试图弄清楚我做错了什么。原来答案是“走得不够远”,谢谢你提出这个问题

标签: ios core-location cllocationmanager geofencing


【解决方案1】:

区域监控不依赖 GPS。这是蜂窝塔/wifi接入点三角测量。您不应期望水平精度优于 65m。试图用 65m 的精确仪器检测 10m 的运动根本行不通。

我不知道 iOS 在被请求监视半径小于 100m 的区域时会做什么。充其量它只是将半径增加到 100。在这种情况下,您的应用仍然可以工作,但可能不是预期的方式。

为了回答您来自 cmets 的问题,恐怕苹果并没有提供对其核心定位技术的深入见解。这就是开发人员之间产生很多困惑的原因,因为似乎没有任何东西可以按预期工作。对于初学者来说,核心位置 API 旨在强制执行最佳实践以最大限度地减少电池消耗。

如果您想使用小于~​​300m(是的,300 米)的定位服务,您必须使用 GPS。地理围栏无法跟上不断行走的用户的步伐。但是在后台持续使用 GPS 是不行的,因为你会很快耗尽电池,而且你的应用很快就会从用户手机中删除。

地理围栏不需要 GPS,但如果有可用的 GPS 数据,将很乐意使用(即使其他应用请求 GPS 更新)。 GPS 辅助地理围栏工作得非常精确,但我看不出有什么好的理由同时使用这两种服务,因为只需将位置管理器过滤器设置为正确的距离就更简单了。

【讨论】:

  • 那么一些事情:除了位置编程指南和类文档之外,是否有详细的苹果文档来描述这一点?如果我想要更精细的定位服务 (60 m) 或更少,是否可以同时使用 gps 和区域跟踪?谢谢
  • 谢谢,我确保不时唤醒 GPS 以完成我正在寻找的东西。
  • @Mihado "在 iOS 模拟器或设备上测试您的区域监控代码时,请意识到区域事件可能不会在跨越区域边界后立即发生。为了防止虚假通知,iOS 不会发送区域通知,直到满足某些阈值条件。具体而言,用户的位置必须跨越区域边界,离开边界最小距离,并在通知之前保持在该最小距离至少 20 秒。(1/ 2)
  • 具体的阈值距离由硬件和当前可用的定位技术决定。例如,如果禁用 Wi-Fi,则区域监控的准确性会大大降低。但是,出于测试目的,您可以假设最短距离约为 200 米。” (2/2) 来自Apple documentation: Region Monitoring
猜你喜欢
  • 1970-01-01
  • 2017-09-15
  • 2014-09-30
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多