ios - Why am I not getting didEnterRegion or didExitRegion calls when using CLLocationManager's startMonitoringForRegion -
i trying set client's app trigger database update when ios device arrives at/leaves office.
(it's app client's salespeople use in field, customer sites not have network connectivity, client wants database updated salespeople leaves office/return office.)
i never getting didenterregion
or didexitregion
calls.
i have singleton regionsmanager
manages instance of location manager. using cllocationmanager
, startmonitoringforregion
method.
on launch, invoke regionsmanager
creates location manager , set delegate of location manager.
in app delegate's didfinishlaunchingwithoptions
method check uiapplicationlaunchoptionslocationkey
, in case i'm being relaunched region entered/exited, never happens.
i have nslocationalwaysusagedescription
key/value pair in info.plist.
i call cllocationmanager.authorizationstatus
make sure app authorized, , if not call requestalwaysauthorization
.
once verify app authorized, check ismonitoringavailableforclass(clcircularregion).
assuming monitoring available, check see if location manager's set of monitoredregions
contains region create (i check coordinate). if so, skip adding region.
if location manager not yet monitoring region, add call startmonitoringforregion
.
on second launch of app, see regions added on last launch in location manager's set of monitoredregions
, know being added.
the code set quite involved, since set handle adding multiple regions, , has logic maintain array of regions being monitored , block should invoked if on didenterregion
or didexitregion
message.
here method in question in it's (rather long) entirety:
func startmonitoring(#coordinate: cllocationcoordinate2d, radius: cllocationdistance = regiondistance, id: string = "", notificationblock: regionnotificationblock) { var authorizationstatus = cllocationmanager.authorizationstatus() if !locationmanagerready { //make sure we're authorized use location manager. if authorizationstatus == .notdetermined && !waitingforauthorization { //we haven't been authorized yet. trigger prompt user. thelocationmgr.requestalwaysauthorization() waitingforauthorization = true authorizationstatus = cllocationmanager.authorizationstatus() } //wait user grant/deny permission. if authorizationstatus == .notdetermined { //after 1 second, re-call method 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 access location denied") return } else if !cllocationmanager.ismonitoringavailableforclass(clcircularregion) { utils.showalertonvc( rootvc, title: "location manager error", message: "geofencing not available.") return } } if !locationmanagerready { locationmanagerready = true thelocationmgr.desiredaccuracy = kcllocationaccuracybest thelocationmgr.distancefilter = kcldistancefilternone; } //if here, we're done configuring location manager //if region in our array of regions, don't add again. if let existingregionindex = regionindexforcoordinate(coordinate) { return } let regiontomonitor = clcircularregion( center: coordinate, radius: radius, identifier: id) //see if system still monitoring region previous launch. var found = false var foundregion: clcircularregion? = nil if let monitoredregions = thelocationmgr.monitoredregions nsset? { let regionsarray = monitoredregions.allobjects 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 (\(coordinate.latitude),\(coordinate.longitude)). id = '\(id)'") thelocationmgr.startmonitoringforregion(regiontomonitor) } let aregionentry = regionentry(region: regiontomonitor, regionnoticeblock: notificationblock) regionsbeingmonitored.append(aregionentry) }
my regionsmanager class has array regionsbeingmonitored
of regionentry
objects:
lazy var regionsbeingmonitored = [regionentry]()
here regionentry object:
class regionentry: nsobject { var theregion: clcircularregion? var theregionnoticeblock: regionnotificationblock? init(region: clcircularregion?, regionnoticeblock: regionnotificationblock?) { theregion = region theregionnoticeblock = regionnoticeblock } }
it has state flags keep track of setup of location manager:
var waitingforauthorization: bool = false var locationmanagerready: bool = false
i have gone on documentation on setting region monitoring quite , pretty confident doing setup supposed doing.
my didenterregion , didexitregion methods write message log file called, if there problem logic matching region entry in regionsbeingmonitored
array should still see log entry:
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) } } }
do see might doing wrong? method signature didenterregion
or didexitregion
looks correct, don't think that's it.
Comments
Post a Comment