为什么我在使用CLLocationManager的startMonitoringForRegion

时间:2015-05-29 13:51:24

标签: ios swift cllocationmanager geofencing region-monitoring

我正在尝试设置客户端应用,以便在iOS设备到达/离开办公室时触发数据库更新。

(它是我的客户和销售人员在现场使用的应用程序,其中一些客户站点没有任何网络连接,因此客户希望在销售人员离开办公室时更新数据库/回到办公室。)

我永远不会收到didEnterRegiondidExitRegion来电。

我有一个单身RegionsManager来管理位置管理器的实例。 我使用CLLocationManagerstartMonitoringForRegion方法。

启动时,我调用RegionsManager创建一个位置管理器,并将自己设置为位置管理员的代表。

在我的应用代表的didFinishLaunchingWithOptions方法中,我检查UIApplicationLaunchOptionsLocationKey,以防我重新启动输入/退出的区域,但这种情况从未发生过。

我在info.plist中有一个NSLocationAlwaysUsageDescription键/值对。

我致电CLLocationManager.authorizationStatus以确保该应用已获得授权,如果没有,请致电requestAlwaysAuthorization

一旦我确认该应用已获得授权,我还会检查isMonitoringAvailableForClass(CLCircularRegion)。

假设监控可用,我然后检查位置管理器的monitoredRegions集是否已经包含我要创建的区域(我只是检查坐标)。如果是这样,我会跳过添加区域。

如果位置管理员尚未监控该区域,我会通过调用startMonitoringForRegion来添加它。

在应用程序的第二次启动时,我看到我在上次启动时在位置管理器的monitoredRegions集中添加的区域,因此我知道它们已被添加。

设置所有这些的代码非常复杂,因为它设置为处理添加多个区域,并且还具有维护被监视区域数组的逻辑以及如果on { {1}}或didEnterRegion消息。

以下是有问题的方法(相当长)整个:

didExitRegion

我的RegionsManager类有func startMonitoring(#coordinate: CLLocationCoordinate2D, radius: CLLocationDistance = regionDistance, id: String = "", notificationBlock: regionNotificationBlock) { var authorizationStatus = CLLocationManager.authorizationStatus() if !locationManagerReady { //Make sure we're authorized to use the location manager. if authorizationStatus == .NotDetermined && !waitingForAuthorization { //We haven't been authorized yet. Trigger a prompt to the user. theLocationMgr.requestAlwaysAuthorization() waitingForAuthorization = true authorizationStatus = CLLocationManager.authorizationStatus() } //Wait for the user to grant/deny permission. if authorizationStatus == .NotDetermined { //After 1 second, re-call this method to try again. delay(1.0) { ()-> () in self.startMonitoring( coordinate: coordinate, radius: radius, id: id, notificationBlock: notificationBlock) } return } let rootVC: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController if authorizationStatus == CLAuthorizationStatus.Restricted || authorizationStatus == CLAuthorizationStatus.Denied { Utils.showAlertOnVC( rootVC, title: "Location manager error", message: "Permission to access location denied") return } else if !CLLocationManager.isMonitoringAvailableForClass(CLCircularRegion) { Utils.showAlertOnVC( rootVC, title: "Location manager error", message: "geofencing is not available.") return } } if !locationManagerReady { locationManagerReady = true theLocationMgr.desiredAccuracy = kCLLocationAccuracyBest theLocationMgr.distanceFilter = kCLDistanceFilterNone; } //If we get here, we're done configuring the location manager //If this region is already in our array of regions, don't add it again. if let existingRegionIndex = regionIndexForCoordinate(coordinate) { return } let regionToMonitor = CLCircularRegion( center: coordinate, radius: radius, identifier: id) //See if the system is still monitoring this region from a previous launch. var found = false var foundRegion: CLCircularRegion? = nil if let monitoredRegions = theLocationMgr.monitoredRegions as NSSet? { let regionsArray = monitoredRegions.allObjects as NSArray let regionIndex = regionsArray.indexOfObjectPassingTest() { (object, index, flag) -> Bool in if let region = object as? CLCircularRegion { return region.center.latitude == coordinate.latitude && region.center.longitude == coordinate.longitude } else { return false } } found = regionIndex != NSNotFound if found { foundRegion = regionsArray[regionIndex] as? CLCircularRegion } } if found { logToFile("already monitoring (\(coordinate.latitude),\(coordinate.longitude)). ID = '\(foundRegion!.identifier!)'") } else { logToFile("Adding geofence for (\(coordinate.latitude),\(coordinate.longitude)). ID = '\(id)'") theLocationMgr.startMonitoringForRegion(regionToMonitor) } let aRegionEntry = RegionEntry(region: regionToMonitor, regionNoticeBlock: notificationBlock) regionsBeingMonitored.append(aRegionEntry) } regionsBeingMonitored个对象的数组:

RegionEntry

这是RegionEntry对象:

lazy var regionsBeingMonitored = [RegionEntry]()

它还有状态标志来跟踪位置管理器的设置:

class RegionEntry: NSObject
{
  var theRegion: CLCircularRegion?
  var theRegionNoticeBlock: regionNotificationBlock?
  init(region: CLCircularRegion?, regionNoticeBlock: regionNotificationBlock?)
  {
    theRegion = region
    theRegionNoticeBlock = regionNoticeBlock
  }
}

我已经仔细阅读了关于设置区域监控的文档,我非常有信心我正在做我应该做的所有设置。

我的didEnterRegion和didExitRegion方法在调用它们后立即将消息写入日志文件,因此,即使我的逻辑存在问题,我的逻辑仍然存在我的var waitingForAuthorization: Bool = false var locationManagerReady: Bool = false 数组中的条目匹配区域请参阅日志条目:

regionsBeingMonitored

你看到我可能做错了吗?我func locationManager(manager: CLLocationManager!, didEnterRegion region: CLRegion!) { logToFile("In \(__FUNCTION__). region = \(region)") if let region = region as? CLCircularRegion { if let regionIndex = regionIndexForCoordinate(region.center) { let aRegionEntry = regionsBeingMonitored[regionIndex] aRegionEntry.theRegionNoticeBlock?(region: region, didEnter: true) } } } func locationManager(manager: CLLocationManager!, didExitRegion region: CLRegion!) { logToFile("In \(__FUNCTION__). region = \(region)") if let region = region as? CLCircularRegion { if let regionIndex = regionIndexForCoordinate(region.center) { let aRegionEntry = regionsBeingMonitored[regionIndex] aRegionEntry.theRegionNoticeBlock?(region: region, didEnter: false) } } } didEnterRegion的方法签名看起来是正确的,所以我不认为这是正确的。

0 个答案:

没有答案