Core Location skips user movements with CLVisit monitoring turned on - ios

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.

Related

CoreLocation - visits monitoring

I am facing issues when using visits monitoring service of coreLocation. When I use visits monitoring, the location update is inconsistent. What exactly is considered as a visit in corelocation?
This is how I start visits monitoring
self.manager.startMonitoringVisits()
I also have added all the CLLocationManagerDelegates.
The documentation is quite ambiguous about what a visit is defined as. As reported by this article
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.
CLVisit has a lot of shortcomings ranging from arrivalDate accuracy to horizontalAccuracy precision.
Instead of relying on CLVisit, try using the Significant Location Change Service
I have an app in the store that uses visit tracking.
I find visit monitoring is pretty accurate. I have never had it detect a red light as a visit, for example. Comparing the reported visit times against an actual record of where I was is also pretty accurate.
The only real inaccuracy I have seen is the actual GPS coordinates and that is more a factor of being indoors or in an inner city area where gps accuracy is reduced.
While Apple does not document how their algorithm works, I suspect that they uses more than just GPS when determining visits; Is the device connected to a car kit? what type of motion occurred prior to and after the "stop" (If motion is smooth and fast before and after you are probably in a vehicle).
One thing to be aware of with visit tracking is that you can receive an initial CLVisit with just an arrival date and then later get an update with the arrival and departure dates filled in.
You can also expect some latency between when you arrive at a location and when you get the initial CLVisit to your delegate, but the arrival date is "back dated" to when iOS determined that the visit started.

In iOS11, how to keep a background task running past 10 min?

My question involves keeping an app that monitors user interactions in the background, for example time spent in one or the app. The issue arises when you can not have a background process run for more than 10 min or violate Apple's sandbox restrictions. Since I am relatively new to the Apple API, and could not find a direct answer that didn't involve location services or VOIP (which are both interesting options, but my application will not be able to use either viably), I come to ask for options in which I can understand when another app opens, when it closes, when it fetches data, and when user holds phone in certain orientation (ie when people hold their phone at certain angles to read text and etc.) for certain amount of time.
The purpose of this analyzation is to predict an attention span for the user, so I need to be able to run in the background, as the user will not be using my app while it predicts attention span.
My thoughts on this are possibly accessing the system log, and somehow parse previous statements (I don't think sandbox will allow), but inevitably the iOS system will suspend my processes after some point unless I put a timer. There is also the option of having the system wake up my app via opportunistic fetching, but that won't be useful if I don't collect the data.
Keep in mind this is within IOS 11, so it is much more restrictive than previous iterations. I understand this may seem like a complex problem, but even a direction in which to head could be useful to me.
This solution might work, (not recommended since it drains the battery quicker).
Just update your current location, every 10 mins. It will reset the background thread timer.

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.

Switch btw. Location Manager & Region Monitoring

for an app that is part of a scientific study I have to implement location tracking (the users who take part in the study know this and are willing to supply this data). The two premises for this app are:
track the user's location with the highest accuracy possible while he/she is on the move
use as little power as possible so that users don't feel the need to shut down the app (turn off location services for it), while they aren't using it
I know these two requirements normally exclude each other :) So the general question is "What would be the best strategy to meet in the middle here?"
My thoughts were to monitor as usual with the highest accuracy possible while location changes keep coming in. If we detect that the delta between theses location updates become almost 0 over a certain period of time, we would assume that the user is not "on the move" anymore and would switch to region monitoring (with a radius of e.g. 40m). Once the user exits that region we'd switch back to regular location monitoring.
So two questions:
Can you tell me if the proposed approach will work for an app that is running in the background?
Have you maybe implemented something similar and know if it really saves a lot of battery power?
Regards,
Sebastian
My thoughts were to monitor as usual with the highest accuracy possible while location changes keep coming in. If we detect that the delta between theses location updates become almost 0 over a certain period of time, we would assume that the user is not "on the move" anymore and would switch to region monitoring (with a radius of e.g. 40m). Once the user exits that region we'd switch back to regular location monitoring.
Using region monitoring to re-engage the location monitoring has a few draw backs, that I have found:
If you set up a region for the user's current location, then wait for -didExitRegion to fire, you're reliant upon the system's default radius cushion, (probably 200m) and some time (probably 20 sec) after they cross out of their boundary before you'll get the message. If accuracy is your main goal, you're likely to loose a lot of data points in between when region monitoring started and when you cross out of the region. Is that acceptable for your needs?
So, to answer your questions:
Can you tell me if the proposed approach will work for an app that is running in the background?
You should not have any trouble running this type of thing in the background. Both location monitoring and region monitoring work when an app is backgrounded, provided you've set it up to do so. Also, to ensure Region Monitoring works on iOS 7 you must have Background App Refresh turned on for your app. That tripped me up.
Have you maybe implemented something similar and know if it really saves a lot of battery power?
In our experience the battery savings were not noticeable. Region Monitoring can be a battery drain that's just as significant as the high accuracy location updates because it uses all kinds of hardware to do it's thing. So pick your poison. Apple's recommendation for saving battery is and always has been to use the significant change location service. It gives you good location data just not as often.

consistency of regionMonitoring

I am curious about why my app does not notify me sometime when I set it to be notified at same spot everyday. On iPhone 4x devices, the app uses regionMonitoring. Somedays the update is received, some days it is not.
Moreover, with significantLocationChanges also (on 3GS), the updates are not received consistently.
1) As I understand, both significantLocationChange and regionMonitoring receive updates when the device is handed off from one cell tower to the next one. Does it mean that users who live in area where the cell towers are not close by, the app will not work?
So, when there are no other parameters that can change, I am really puzzled by this behavior.
2) Does it mean that users who live in area where the cell towers are not close by, the app will not work?
3) Can I rely on regionMonitoring to notify the user consistently? What is the recommendation?
Regards. Sam.
regionMonitoring benefits from a couple other inputs to location monitoring. It triggers based on WiFi connections as well as other applications using location. Any location updates the OS receives will get run for any outstanding regions being monitored. The older significantLocationChanges is basically stuck to cell tower handoffs, and is generally less reliable in sparse cell areas.
Doesn't mean it won't work, it will just be less effective or useful.
My experience says that the regionMonitoring is the most consistent and reliable way to monitor locations without actively using GPS. It is by no means perfect, but for the majority of users, it should work with little to no issues.
I have an app that uses region monitoring and I haven't had any major complaints about accuracy at all. I made the decision to not support the 3GS and the older method for 2 reason. Few users using it, and getting smaller by the day. Secondly, it is a lot more code to support for much less accuracy and I didn't want it to detract from the overall experience, so I left it out. Hope this helps.

Resources