CoreMotion and iBeacons in background mode

Hello All,


I’ve created application which logs motion activity of user with CoreMotion framework and M7-chip functionality (I’m using CMMotionActivityManager).

Application works fine in foreground. But I need to check that event occurred in 3-7 seconds frame in background mode.


And I need to range iBeacons - check entering to specified zone in background mode and activate my test for the motion event

.According following review http://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html

the time for detection is about 4 minutes (in average and up to 15 minutes) in background mode.


Does exist any method or workaround to grab data for motion activity and ranging iBeacon in the background with better accuracy?

- I need to check that event occurred in 3-7 seconds frame and notify user.


My concept application works in the following way:

1. I’ve activated background mode flags for CoreLocation and Audio (it plays audio signal on event detection).

2. At start it requests authorization “always” for Core Location

3. On success it launches CLLocationManager updates with desiredAccuracy = kCLLocationAccuracyBest and distanceFilter = 4.0 meters.

4. then it starts motion activity tracking with CMMotionActivityManager::startActivityUpdatesToQueue for main queue.

5. The handler for motion activity updates save logs with location coordinates to file and notifies user when event detected.


Expected results:

The detection for event should be logged in time (with upper limit 3-7 seconds for activity timestamp).

The application should save coordinates which precisely shows the place when it occurred.


Actual results:

The updates from motion activity manager comes with big random pauses up to 5-6 minutes

and in this case my detector can’t guarantee that event occurred(or not) during these pauses.

I’ve used iPhone 6 for my tests.

First off, getting on my soap box, I have to ask what exactly you're trying to do?



Reading between the lines, it seems like you're trying to mix these three technologies together and run for an extended period of time in the background Trying to make what you're describing work is going to absolutely destroy battery life to the point of making any sort of "just let this run all day" application nonviable. Related to that:



>- I need to check that event occurred in 3-7 seconds frame and notify user.



For apps that run in the background, many problems start at the requirements phase not the implementation. An iPhone CANNOT detect events within that narrow a time scale without running continually. And an iPhone CANNOT achieve good, all day battery life while being used continually. Now, it's possible that your particular app falls into some particular special case that makes this a non-issue, but if you're your app is a traditional app that directly targets consumers then you simply can't meet that requirement and have decent battery life. No combination of API usage will avoid that. The solution is to change your underlying design/requirements.



Now, as to the technical problem:



> The updates from motion activity manager comes with big random pauses up to 5-6 minutes

> and in this case my detector can’t guarantee that event occurred(or not) during these pauses.

> I’ve used iPhone 6 for my tests.



Yes. In foreground, CMMotionActivity delivers a more constant data stream primarily as an aid to realtime analysis. For example, if you take an extended run and log CMMotionActivity events you'll see a relatively steady stream of almost identical activity events (running, running, running, running, running...) that differ only in their "CMMotionActivityConfidence" property. In the background, the behavior shift to behave more like the historical API and generally only returns data when the activity changes (running, <5 min pause>, walking...). In between events, you should assume that the user is simply continuing the last activity your app was notified of.



-Kevin

Hi Kevin,

Thanks for the really informative reply. While my use case doesn't sound the same as dmlad's I am running into the same issue with CMMotionActivity and was hoping you could expand a bit. Hopefully this isn't too wide a digression.


Specifically, I'm seeing that often when I call queryActivityStartingFromDate in the background, I get no activities returned. If I then bring the app into the foreground and re-call queryActivityStartingFromDate for the same exact time period, I get results. For my use case, I don't need continual updates but I do need to be able to check and find out what activity the system found while I am in the background. I'm trying to avoid using startActivityUpdatesToQueue because it would keep my app active in the background continually and result in a lot more battery drain than one historical query at the end. Is there a way to do this?


Best,

William

CoreMotion and iBeacons in background mode
 
 
Q