When previously working for a client I had the chance to create a proof of concept (POC) that enabled uses to be notified via Apple's Push Notification Service or third party tool when entering a chosen boundry. Once entered into a specific boundry a user would be shown information to interogate alowing with targeted advertising.
The main issue faced was around accuracy. iPhones are currently accurate to a radius of 10-15m and uses on average 2 cell tower GPS locations to provide the coordinates that pin point the device. While it isn't true GPS it's still an accurate way to determine a users location. The second issue would be the drawing of these boundries inconjunction with receiving notifications (performance issue). Having gone through various scenarios the solution to store and cache data once a user had entered a location seemed the best of the bunch. Under this solution the server and the device interaction would be small (push notification size) and keep costs low at server level.
Having advised on how the back end services would handle the transferring of data between entites the POC was created. The POC was delivered ahead of schedule and testing began. Both myself and the client visited various locations throughout the UK and with the back end guys on speakerphone we tested Guerrilla style. Under testing we found an issue relating to device notification queuing and removal, but that was an easy fix. If that's one takeaway from this article is that you should test your applications under the scenario that it would be used in, don't just rely on the simulator.
Overall the project was a success and the POC proved a viable MVP for the client to attract investors. The client managed to secure funding and the application was built by a small team I helped create. Whilst the bulk of the code is propietory and bound by an NDA what I can share is the Swift 3 code example below. This is how to draw a boundry around a set of coordinates pulled from Core data, It looks like a small chunk but under a MVCS pattern each "Bulk" workload is farmed off to the service class it represents i.e. UserService, CoreDataService. This keeps controllers clean to "Control" and decouples logic allowing for separation of concerns.