位置管理器didExitRegion未被调用

Mih*_*ado 5 core-location cllocationmanager ios geofencing

我已经设置了委托,创建了一个区域,并且我已经阅读了所有文档.每次用户的位置发生变化且位于指定区域之外时,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)
            }
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*lov 4

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

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

从评论中回答你的问题,恐怕苹果并没有提供对其核心定位技术的深入见解。这就是开发人员之间产生很多困惑的原因,因为似乎没有什么能按预期工作。首先,核心位置 API 旨在实施良好实践,以最大限度地减少电池消耗。

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

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