Foursquare API: Consider close proximity as check-in - ios

I've been looking into the Foursquare API on iOS (through das-quadrat). I'd like to figure out if a user is at a specific location. I know how to find it and I can actually get it. That works.
How can I now tell if the user is actually close enough to the location to consider his close proximity as a check-in (I'm not interested in actually checking him in the Foursquare way)? It's just that I want to know that a user is at a venue of a category I'm monitoring. I know that I can just calculate the distance between the user's location and the venue's location and consider every distance less than, say, 15 meters a check-in but I was wondering if there's is a more elegant solution, maybe even an API endpoint that I'm just missing.

I would guess that the real time API is best suited: https://developer.foursquare.com/overview/realtime
Allows you to register for notifications, thus Foursquare does the heavy lifting for you.

Related

Core Location skips user movements with CLVisit monitoring turned on

The app I'm working on records information about places where user spends most of his/her time. Core Location's Visits monitoring fulfil all it's requirements in location information absolutely.
While testing this app our QA-engineers revealed evidence that Core Location misses Visits for unknown reason. And this is not a result of low location accuracy. Core Location starts skipping locations registered before without any problems.
To make things clear we've run the test. I installed on his phone our app and example app: https://github.com/steveschauer/TestCLVisit
After 3 days of testing we compared locations from our app, sample app and information from Settings->Privacy->Location Services->System Services->Frequent Locations.
Information from all sources was equal. So we can say that it's not an issue of our app.
But while all locations registered at first day was correct, many locations of second and third day were missed. Only few of them were registered.
Is it normal behaviour for Visits Monitoring?
What could be a reason of such skips?
Does anybody have negative or positive experience of Visits monitoring?
Yes, I faced some similar issues while using CLVisit API. There is also an article from NSHipster, which describe some issues with CLVists and these are still present in iOS 10. It essentially goes on to say that if you want infrastructure that extremely precise don't use CLVisit.
From our experience, CLVisit is not all that precise. While start and end times are generally accurate within a minute or two, lines get blurred at the edges of what is and what is not a visit. Ducking into a corner coffee shop for a minute might not trigger a visit, but waiting at a particularly long traffic light might.

How does CLVisit work?

I am working on a app that relies heavily on monitoring user visits in possibly multiple regions / areas. I am currently experimenting with region monitoring which works pretty well, however, the location callback is not as accurate as I want it to be. I have seen CLVisit, but the documentation out there doesnt explain it very well, especially its use.
I think you are misunderstanding the concept of CLVisits. There is actually no Visit object that you need to create. The CLLocationManager delegate method is triggered by the algorithm that apple has determined (see wwdc lecture for more info). This is explained in the CLLocationManager documentation...
Getting the Visited Locations
In iOS, the visits service provides an alternative to the significant location change service for apps that need location information about interesting places that the user visited. For example, if the user is in one location for an extended period of time, the service might generate an event when the user arrives at that location and another when the user leaves that location. The service is intended for apps that might already be using the significant location change service and want an even lower power way to do so. You would not use this service to create navigation apps or apps that rely on regular location updates.
To begin the delivery of visit-related events, assign a delegate to the location manager object and call its startMonitoringVisits method. As the location manager generates visit events, it delivers that information to its delegate’s locationManager:didVisit: method. The event data delivered to your delegate includes only the information that occurred after you started the delivery of events. In other words, if you start the delivery of events after the user arrived at an interesting location, the event delivered by the system when the user departed that location would not reflect the actual arrival time. If the system terminates your app, this service relaunches it when new visit events are ready to be delivered.
That said if you look at this article from NSHipster, it references some current issues with CLVists (for iOS 8.1). It essentially goes on to say that if you want infrastructure that extremely precise don't use CLVisit. Seems like you're doing it right (for now at least).
CLVisit is, as of iOS 8.1, not all that precise. While start and end times are
generally accurate within a minute or two, lines get blurred at the edges of
what is and what is not a visit. Ducking into a corner coffee shop for a minute
might not trigger a visit, but waiting at a particularly long traffic light
might. It’s likely that Apple will improve the quality of visit detection in
future OS upgrades, but for now you might want to hold off on relying on CLVisit
in favor of your own visit detection for use cases where it’s vital your data is
as accurate as it can be.

Determine whether user is at a specific location

What's the best way to determine whether the user is at a specific location, i.e. at a gas station?
I've implemented an approach where the app is listening for major location changes until the user get's close enough to a location. Then the app switches to the more accurate location updates (kCLLocationAccuracyBest). It then checks if the user is close enough, and if so, I consider this as a "check-in". This works quite well. If the user moves away from our location of interest, I switch back to the major location updates to save energy.
This works as the user does not live or work within the first threshold (I currently use 300 meters). This situation drains the user's battery for no reason. If I set this threshold to low, the major location updates might not be accurate enough to detect the user in front of our location.
I'm using MKLocalSearchRequest to find all the places of interest in close proximity to the user.
So, I assume there are better ways. Any suggestions?
Thanks!
– Flo
iBeacons are the low power way if that fits your use case. http://en.m.wikipedia.org/wiki/IBeacon Is a suprisingly good overview
They are reasonably cheap, and can be simulated with computer software

CLLocationManager not very accurate inital updates

This is stated in CLLocationManager class reference:
When requesting high-accuracy location data, the initial event delivered by the location service may not have the accuracy you requested.
This is really affecting my app. How can I make sure that the location found is the one with the correct accuracy?
I tried to use the 4th or 5th update rather than first retrieved location but this is not a good solution. Any idea?
You should check the accuracy of the updates, CLLocation
contains a property horizontalAccuracy which you can use to check the accuracy.
When the CLLocation has an accuracy that you find accurate enough you use and ignore al others.
Als you should tel CLLocationManager your desired accuracy. To do this set the desiredAccuracy property in CLLocationManager.
I think you will have to live with that. That's how Apple implemented it. Getting a fine grained position takes time, just think about how long any windshield-mounted GPS devices in cars take to fix up their position.
So instead of letting your application wait for a longer time, they provide with what accuracy is available almost immediately, based on cell-towers and WiFi hotspots in the vicinity. Only when there has been a more reliable GPS fix will they call into your app again and let you know.
In the end, it is just a question of where the waiting for the fine-grained position is: In your app, where you have the chance of doing something with the more coarse-grained data you get quickly, or in their framework with no chance for apps to do anything useful in the meantime. I think, letting you decide is the better choice.
Depending on the type of app, you could have a map that automatically zooms in deeper as soon as better position data comes in, draw a smaller circle around the position you are expecting etc. For the end user, nothing's worse than waiting without getting any feedback. So even though this is probably not the answer you would have liked, I advise to make the best of it from a user's perspective.

Best way to monitor for a large (50000+) number of regions

I want to create an app which does a specific action when the user enters a certain area.
Since the regions I want to monitor reside server-side (approx. 50.000 locations) and the number of regions is far too large to be registered for monitoring all at once, I want to start monitoring for regions which are close to the current location of the user.
To accomplish this I am thinking about using startMonitoringSignificantLocationChanges
to monitor whether the user has changed location and then use locationManager:didUpdateToLocation:fromLocation:
to register new regions to monitor and unregister regions which are now too far away.
My questions:
Am I allowed do a call to a
web-service in
didUpdateToLocation while the app is
in the background?
Is this the best way to implement this kind of functionality or do you
know of a better way?
Thanks.
What you want is a space-filling-curve for example a z-curve of a hilbert-curve. It reduce the 2D problem to a 1D problem but it's most likely not answering your question.

Resources