Why iOS app iBeacon wake up intervals varies? - swift

Hi i have a swift app that communicate with a BLE device with a beacon.
When i kill the app the beacon wake the app in background and it connect to the device and start communicating.
The interval of detection / connexion mostly take between 30 sec to up to 1 min after i kill the app. but sometime it take like 3 4 min.
Did anyone faced such issue and have an idea of whet could be happening it's the same process why it vary from time to time did it have a relation with the device itself ?
thx

Since iOS is closed source, it is impossible to say with certainty why delays in beacon detection happen. This is especially true in individual cases -- there are lots of variables.
However, we do have some ideas of how iOS CoreLocation manages to detect beacons based on reverse engineering, and I have some insight on based on building the Android Beacon Library which uses similar concepts.
Here is what we do know:
CoreLocation uses BLE hardware filters for pattern matching to get detections as quickly as possible. If a hardware filter slot is available, beacon monitoring will use the Bluetooth chip itself to look for a pattern first matching. This will give you a detection in less than a second when a beacon first appears.
In some cases hardware filters cannot be used (they are exhausted) or the beacon is known to be in the vicinity, so it is ignored. In these cases, a periodic backup scan is used to look for beacons.
The backup scan happens at different rates depending not the state of the phone and the beacon/bluetooth scanning state of apps running on the phone. If no apps are actively scanning and the screen is off, this can be every few minutes.
When the screen is turned on, it typically triggers a backup scan.
If your app is visible in the foreground and using ranging APIs or actively doing a BLE scan with CoreBluetooth, it is scanning at a 100% duty cycle.
In other cases, the duty cycle will be lower. If you are testing with a beacon that does not advertise frequently (e.g. less than the 10Hz in the iBeacon spec) it may miss detections at 10% duty cycle scan.
A few things to consider based on your description:
You may have exhausted all of the BLE hardware filters on your phone, and your app may not be getting one. Unfortunately, this optimization is completely hidden, so there is no way to tell for sure. You can increase the chances of getting a hardware slot by uninstalling any apps you think may be scanning for Bluetooth, then uninstalling and reinstalling your app, and restarting the phone. If all else fails, do a factory reset on a test phone.
Whenever you reboot your phone, it takes much longer for things to be fully booted than it appears. Location services are amongst the last things to be fully initialized. Always wait 5 minutes after reboot before doing any time-sensitive testing.
It takes time for iOS to detect it is in an out of region state with a beacon. This is typically 30 seconds if the app is visible on the screen, but if it is not, it may take significantly longer because of the timing of backup scans. And you cannot get a new region entry event if iOS doesn't realize you have exited yet.
If you kill your app when a beacon is visible (or when it had recently been visible) iOS may not know the in region / out of region state. If it thinks it is in region when it is not, it can take a long time to figure out it is out of region.

Related

Requesting location in watchOS and its effects on battery

I am trying to create a low-power watchOS app that will only periodically (every 5 minutes or so) need an updated but precise location. The key word there is need. The app certainly could provide better information if it were getting location updates consistently but the goal is for this app to be low power. That being said (and I am not sure if this is possible) if another app is constantly streaming location in the background it would be nice to get those updates too if that does not have extra battery cost.
Is there a way to only request location periodically? Is this actually better for the energy impact of the app?

CLLocationManager geo-fencing/startMonitoringForRegion: vs. startMonitoringForSignificantLocationChanges: vs. 10-minute startUpdating calls

I am trying to set up an app that will be able to check people's locations in the background, see if they are at a given location, and send a ping to a server if they are. We do not want to drain the energy of our users, so we are attempting to figure out the best solution.
I've done substantial reading and I have not found very much information on these methods. I'll go through the pros and cons as I understand them right now
startMonitoringForSignificantChanges
Description: Based off of wi-fi and cell tower changes the system wakes up the app.
Docs:
Apps can expect a notification as soon as the device moves 500 meters
or more from its previous notification. It should not expect
notifications more frequently than once every five minutes. If the
device is able to retrieve data from the network, the location manager
is much more likely to deliver notifications in a timely manner.
Pros:
Most battery efficient
Cons:
Dependent on wi-fi/cell tower changes
Can only assume that this will be called every 200m to 2km (if not more in certain areas)
More on accuracy
Thus, inconsistent and imprecise
10-minute start-updating or "n-minute updating":
Description: This basically asks the app for more time, when that extra time is about to expire, it calls [self.locationManager startUpdating], grabs the location and extends the background thread for 10 more minutes.
Pros:
Consistent
Can be as accurate as you want it to be as consistently as you
want it
Cons:
Has to do a call every ten minutes or less to keep the app running in the
background (ie n can't be greater than 10 for the calls)
Questions:
What effect does this have on the battery? Does waking up the GPS and shutting it off hurt the battery more? I couldn't imagine running a brief location check in the background would drain the battery that much... but then again, I don't know what goes into powering up the GPS and getting a usable signal.
startMonitoringForRegion (geo-fencing):
Simply put, your app gets woken up when you enter into a pre-defined region. This is the oddball of them, it is more recent and there is less documentation on it. I can't find a good description on how the "system monitors" the boundary crossing. For all I know it is some really smart algorithm, or they are constantly pinging the GPS which would make it less effective than the other methods for doing this.
Pros:
Simple implementation
Managed by the system so you don't have to invent your own ad hoc geo-fences Only triggers on boundary crossing... no unnecessary data to just throw out in exchange for a battery hit
Thus, should be the best for this sort of thing, accurate, managed by the system
Cons:
People question its effectiveness
Huge conflicts on whether or not it is good for battery life or if it
drains battery life terribly.
How is the system monitoring this!?
Basically, indeterminate behavior.
I guess my question boils down to how does startMonitoringForRegion: compare to these other methods of testing user location in the background when it comes to battery life, consistency, and precision. Has anyone thoroughly tested this? Or used it in their app and gotten at least some feedback? Likely, for my purposes, the trade-off is between geo-fencing and the 10 minute update method. (Also given what Apple has publicly said about iOS7 there will be some background tasks... will this change the calculus for the trade-off between these two methods?) Does anyone have an idea of how these two compare?
Thanks so much! Looking forward to seeing if we can get to the bottom of how to compare these methods.
I've been working on vehicle tracking using GPS for 2 years. Learned a lot the hard way... In my experience startMonitoringForRegion or Geo-fencing depends upon cell change events, didEnter or didExit events doesn't fire up until there is a cell/wifi change event. So it doesn't make any difference w.r.t battery consumption. However it does extra computation which depends on how many regions currently are being monitored. Even Apple's Reminder app doesn't give good results for location based reminders because it uses geo-fencing.
The other approach starting GPS for n minutes after each m-minutes is good option, it should not affect the battery life, if done wisely. What exactly effect the battery is constant GPS activation in high precision mode. Like for instance If you enable GPS with kCLLocationAccuracyBest and distance-filter = 0, you can literally observe battery drainage and soon your device will also start getting hotter.
If I was you, I would go for activating GPS after every 10 minutes for 5 sec with kCLLocationAccuracyBest (or may kCLLocationAccuracyNearestTenMeters to use less battery, if accuracy is not that much important) and distance-filter = 5 (meters). Battery consumption in this case will be unnoticeable. You can play around with similar settings which can address your specific case and finally find out what is best you.
BTW: iPhone uses AGPS, A-GPS additionally uses network resources to locate and use the satellites in poor signal conditions. So, when you do startUpdatingLocation it will also use nearby cell tower information. see http://en.wikipedia.org/wiki/Assisted_GPS

How to run ios application in background on device restart?

I am working on Location Tracking Application. This application continuously send location even in background. I am using SLC property.
I am also using silent push trick for location tracking. Logic of Silent push:
Check AppIconbadge number and perform the action according to AppIconbadge number. I have a timer which check AppIconbadge at every 10 seconds.
Now this is the case:
Device is on SLC and put the app in background and turn off the device. While you switch back to On this device it is still reporting on SLC while Ping (Silent Push) is not working.
I have started the timer when app get SLC trigger. But its not working.
Can you help?
You can't do it.
The way iOS achieves great battery life and reduces RAM usage makes this kind of thing impossible.
Your only real possibility is to have your server send occasional push notifications to the device, and have your app on the device respond with its location. This is how Find My Phone and Find My Friends both work. The idea is to improve battery life by doing as much as possible on a server, which has mains power and virtually unlimited RAM, instead of on the phone which only has a battery and might need all it's RAM to play a 3D game
Basically the CPU is not running at all most of the time, so it can't schedule stuff to run periodically, and you can't rely on there being enough RAM available to run your app so it also can't be running all the time even if the CPU is powered on.
According to the WWDC 2013 keynote, push notifications are much more powerful on iOS 7, so you should look that up (I haven't looked into it myself, just saw the keynote.

How can I locally detect iPhone clock advancement by a user between app runs?

A common exploit in casual games is to artificially advance the system clock to jump ahead in gameplay. How can such user clock advancement be detected by an app on an iOS device?
Must not involve network communication
Must not assume app is open (running or suspended) while clock is advanced
Must detect clock advancement, detecting clock rollback is not sufficient
Ideally, the solution would be robust against reboots, but that is not a requirement.
CACurrentMediaTime & mach_absolute_time
Take a look at this questions:
iOS: How to measure passed time, independent of clock and time zone changes?
Calculating number of seconds between two points in time, in Cocoa, even when system clock has changed mid-way
CACurrentMediaTime uses mach_absolute_time:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreAnimation_functions/Reference/reference.html
Here you have an example on how to use CACurrentMediaTime:
http://www.informit.com/blogs/blog.aspx?b=02b4e309-308c-468a-bab1-cebb1404be6a
Here you have a more information on mach_absolute_time:
http://developer.apple.com/library/mac/#qa/qa1398/_index.html
http://shiftedbits.org/2008/10/01/mach_absolute_time-on-the-iphone/
I was thinking about the fact that the CoreLocation stuff could do this if that part of the GPS data was exposed to you. However that got me thinking.
My only (far fetched) suggestion is to put something into background processing - which has to be for one of a small specific set of reasons, for example to track location in the background. As a side effect of that, try to detect a clock change on a regular timer. Apple might reject it as it may be clear that its not using the location information and its just a reason to exploit background processing.
Any solution not involving networking is so much harder to implement, I wonder why you're not using it.
Whilst I don't think it's possible to reliably determine whether or not a user has manually turned their clock forward without network access, you can of course reliably determine if they've travelled back in time. And since we know this to be physically impossible it can therefore be assumed they have manipulated their clock to cheat.
What I mean by this is, isn't the usual process to trigger some action in-app that requires a period of waiting, exit the app and turn the clock forward, re-launch the app to gain whatever they were waiting for and then reset the clock back to the actual time?
If this is indeed the case, then to build on the suggestion by #smgambel, you could store the physical time and current time-zone on each launch and compare with the previously stored time and time-zone. If the time is behind the previously stored time, and the time-zone of the device hasn't changed then you can safely assume the user has manipulated the clock.

What is active GPS effect on mobile devices battery life?

How much does active GPS drain the battery? Without the overhead of the gps navigator software. s
ay I want to sample the gps every 2 minutes and save it to a file. how much battery power will that cost me?
Will I get 10% shorter life? 20%? ..?
I think this can't be answered that easy without measuring it. But you could measure it. Just try how long it takes to empty the whole battery. Once with GPS and once without.
It will be noticeable by the user. You definitely don't want to do this kind of thing unless it is a feature the user is explicitly aware of and able to clearly turn on and off depending on whether at any particular time they think that feature is worth the impact on their battery.
On my HTC Desire, RunKeeper with GPS always active, battery was near to down after about 5 hours of usage (in forrest).
But the screen was down while it was running, 2 hours of reading pdf drains about 40-50% of battery, so GPS working in background drains about same or less energy than screen active.
When you turn the GPS on, you must wait, depending on where you are, before you get the read, so if you want to save position every 2 minutes, I think GPS will be on about 25%-50% of time. 10 hours of work in background would be max in that case...
Maybe the question about increasing battery life on Windows Mobile using GPS will give some hints, since the device used in test was manufactured by HTC, which is one of the most popular manufacturer of Android Devices nowadays...