Group Group Group Group Group Group Group Group Group

raywenderlich.com Forums

Geofencing Tutorial with Core Location

In this tutorial you'll learn how to leverage the Region Monitoring API baked into Core Location to add geofencing to an app. Forgot your keys? Never again!


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/966-geofencing-tutorial-with-core-location

When I try to run the starter project I receive two errors and one warning. The errors are at lines 42 and 64 of GeotificationsViewController. The first states that “override func prepare(for segue:” does not override anything. The second states that "cannot convert ‘Data’ to expected ‘NSData’ (abbreviated version of error msg).

I’m using xcode 8 gm.

Good catch! Working on getting this fixed ASAP.

The starter project has been updated to work with the latest Xcode.

Hi, thank you for the tutorial. I’d like to handle the 20 limit by creating a Queue, so If I want to start monitoring a region and I’m already at the limit I want to remove the oldest monitored region and add the new one. The way I’m doing it is if I get an error while adding a new geoRegion I stopMonitoring the oldest and start the new one.

My question is: being both startMonitoringForRegion and stopMonitoringForRegion async I’m afraid that doing something like:

self.locationManager.stopMonitoringForRegion(oldRegion)
self.locationManager.startMonitoringForRegion(newRegion)

could raise unwanted errors if stopMonitoring didn’t actually stopped before startMonitoring wants to add a new region. Do you know if it’s safe to do that? Unfortunately there’s no didStopMonitoringForRegion call.

Hi! Thanks for this great tutorial. I have a cuestion, it’s a good practice put all code about cl location manager in the AppDelegate class? Thank you!!

It makes sense here since the AppDelegate is the one conforming to the location manager delegate, and it’s such a small amount of code. It is, naturally, up to you to make the decision if it needs to be in another file. Depends on how much you like punishing future developers with a 1000+ line AppDelegate file ;]

1 Like

Hey, if there a way of please getting the previous version of this tutorial? The one using Xcode 7 and Swift 2? Than you very much in advance!

This error appears in console to run the project in Xcode 8:

ERROR /BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit_Sim/VectorKit-1228.30.7.17.9/GeoGL/GeoGL/GLCoreContext.cpp 1763: InfoLog SolidRibbonShader:
ERROR /BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit_Sim/VectorKit-1228.30.7.17.9/GeoGL/GeoGL/GLCoreContext.cpp 1764: WARNING: Output of vertex shader ‘v_gradient’ not read by fragment shader

1 Like

Good tutorial. I have a question about the rendererFor overlay function. You have the code example to set the strikeColor and fillColor. What if you want to conditionally set the color of the circleRenderer? For example, I added a Bool to the Geotification. I can query this when drawing the pin in

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?

because is can assign the annotation to a Geotification, e.g

let tmp = annotation as! Geotification

BUT, i can’t figure out how to get at the related Geotification inside the rendererFor overlay function. Is there a way to get at the Geotification inside the renderFor overlay function so I can conditionally set the circle colors?

UPDATE ----
I found a work around which was to set up a global variable that stores the value of the geotifidcation that I want inside addRadiusOverlay just before the circle is added. Then I query that global variable inside rendererFor - not pretty but it works.

Thanks

cool tutorial thank you, but I’m facing a problem: I downloaded the final sample project, and added both the Apple & Google geotifications as mentioned exactly in the tutorial (Apple for entry & Google for Exit), but the app fires Apple’s only notification each time it enters the region, that’s so weird …

The same for me but vice versa. I will be only notified on region exit.

@dzensik @muradjamal If you put a breakpoint where the notification occurs, can you see it trying to call for both? It may be an issue with the simulator trying to present two alerts successively.

Thank you so much for this tutorial. Do you think you could help me with just adding a geofence around the user’s location? I know it seems easy but I have not been able to find any way any where.

Cheers

Hey @tupacliv3s,

If you’ve got a CLLocationManager, you can get the user’s current location from there.

i have tried to use only this functions in my project and the didEnterRegion is good its triggered right after simulated user location is entered the region but didExitRegion is triggered after 45 seconds or maybe 200m approximately… i dont know is that some kind of delay or something else …

func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
if region is CLCircularRegion {
// handleEvent(forRegion: region)
print(“enter”)
}
}

func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
if region is CLCircularRegion {
// handleEvent(forRegion: region)
print(“exit”)
}
}

i am using city bicycle ride for testing…

Great tutorial that one i want. Really appreciated.

This app will work in suspended state(After cache cleared) as well?

Aloha Andy,

Great tutorial! I really appreciate the detail and level of explanation that you provided in your tutorial. I’m trying to create a sample project very similar to this however the app has fixed coordinates with geofences. So far, I’ve been able to create geofences around fixed coordinates however, I’m can’t figure out how to code the func note in the AppDelegate.Swift to display notes stored in my array that currently stores both the coordinates and notes (aka region identifiers). If there’s any pointers you could lend me, I would greatly appreciate it. Mahalo!

Hello, is there any way to move circle without changing MAP position without an annotation ?

Hey there, anyone else getting an error at

guard let message = note(fromRegionIdentifier: region.identifier) else { return }
window?.rootViewController?.showAlert(withTitle: nil, message: message)

****use of unresolved identifier ‘window’