Not getting accelerometer and heart rate data when screen is turned off in watchOS 2 - accelerometer

I'm working on apple watch app using CMMotionManager and HKWorkoutSession to get both the accelerometer and the heart rate data. The app works fine for a short period of time (70 seconds), but when the screen is turned off, both the heart rate and the accelerometer data just stops.
My question is how could I get a 5 minutes data from both the accelerometer and the heart rate sensors?

To take more time when app is going to background you can use performExpiringActivityWithReason. This is described here https://developer.apple.com/videos/play/wwdc2015/228/?time=345 On my watch it just takes approx 30 seconds
NSProcessInfo.processInfo().performExpiringActivityWithReason("Reason") {
expired in
if !expired {
let delay: Int64 = 30
let delayTime = dispatch_time(DISPATCH_TIME_NOW, delay * Int64(NSEC_PER_SEC))
dispatch_semaphore_wait(semaphore, delayTime)
} else {
dispatch_semaphore_signal(semaphore)
}
}

Since the release of watchOS 2, HKWorkoutSession is the only way to keep an app running when the watch screen goes off. HOWEVER, the app is in a suspended state. Timers and any other process execution is paused until the screen turns back on. Memory allocations for the app however is preserved. During the time the app is suspended, the device's hardware is still collecting data and storing it on the watch's hard drive. When the screen turns back on the the app come out of suspension and any data that was collected by the hardware is returned at that point to the app (assuming the appropriate listeners were subscribed to).
There is not currently a way to continue to send heart rate data (or any data) from the watch to an iPhone after the screen turns off.

watchOS 2 does not allow apps to run while the screen is off. Although there are ways you can get a bit of extra time, such as with performExpiringActivityWithReason, there is no way to ensure that your app runs for a full 5 minutes.

Now, Apple open an API for recording your Accel data Click:CMSensorRecorder
. whenever your app is suspended or killed, the API will continuous run in 50Hz almost 3 days.

Related

Keeping Apple Watch Awake for more than 70 seconds (watchOS 3)

Is there any way to keep an Apple Watch awake for more than 70 seconds? I understand the purpose of turning off the face to save battery life but I'm trying to sample motion data continuously for about 3 minutes and the sampling is interrupted as soon as the face turns off. I've set the watch to stay awake for 70 seconds every time I tap it, but is there any way to prevent it from turning off for > 3 minutes? I found this post from Feb. of 2016 but haven't found any updates confirming or denying the possibility of preventing the watch face from sleeping in watchOS 3.
If you're looking at sampling motion data like the accelerometer or gyroscope, you can create a HKWorkout Session that will keep your app running in the background. While your Watch face will still eventually turn off without tapping, you will still continue to be able to keep sampling your motion data. Note that only one HKWorkout Session can be run at a time. Hope this helps!

Is it possible to reopen a suspended app after a time delay in Swift?

I am using the following code to suspend the app.
UIControl().sendAction(Selector("suspend"), to: UIApplication.sharedApplication(), forEvent: nil)
do {
print("suspended")
} catch _ {
print("unable")
}
I was wondering is it possible to reopen the app after a certain time delay. Following code works for performing an action after time delay. But I don't know how to reopen the app at that time interval
let seconds = 300.0
let delay = seconds * Double(NSEC_PER_SEC) // nanoseconds per seconds
let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
print("time delay")
})
It's is not possible and apps with such kind of "functionality" will be rejected by Appstore ;)
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/StartingStopping.html
Always Be Prepared to Stop
An iOS app never displays a Close or Quit option
When people switch away from your app, iOS multitasking transitions it to the background and replaces its UI with the UI of the new app. To prepare for this situation, your app should:
Save user data as soon as possible and as often as reasonable. Do
this because an app in the background can be told to exit or
terminate at any time.
Save the current state when stopping at the finest level of detail possible. In this way, people don’t lose their
context when they switch back to your app. For example, if your app
displays scrolling data, save the current scroll position. You can
learn more about efficient ways to preserve and restore your app’s
state in Preserving Your App’s Visual Appearance Across Launches.
Some apps may need to keep running in the background while users run another app in the foreground. For example, users might want to keep listening to the song that’s playing in one app while they’re using a different app to check their to-do list or play a game. Learn how to handle multitasking correctly and gracefully in Multitasking.
Never quit an iOS app programmatically. People tend to interpret this as a crash. If something prevents your app from functioning as intended, you need to tell users about the situation and explain what they can do about it.

App Background issue While in Background

My app is checking some algorithm in the background, after something like 30 minutes
my application seems to be like close (iphone turn to sleep mode i think). I need the app
to run this algorithm as long as it is in the background.
Do you have any idea how to set this 20 minutes timer to recount by some action?
maybe NSRunloop or something else?
You can't reset this timer or continue to run in the background on a stock OS iPhone (except for a limited amount of time, or if your is legitimately of 3 types, VoIP, audio or GPS).
The user can reset this timer by bringing your app to the foreground, perhaps after a notification or something.

Multitasking: Stop Background Audio at Specific Time

I am developing an iphone app which uses background audio (on an infinite loop) to continue playing after the app has entered the background.
My problem is I want to implement a "sleep timer" which stops playback after a specified period of time.
Is this possible? I have spent an hour looking for a method to do this with no avail.
EDIT: My current thought is to use a lower level API, the Audio Queue Services, and manually re-fill the queue with another instance of the loop during the AudioQueueOutputCallback. If the timer has expired I do not fill the loop. I'm assuming this should work since the documentation says audio callbacks are still fired when an app is playing multitasking background audio. Can anyone think of a better way or a reason why this wouldn't work?
While you queue sound data on the background your app remains fully functional and running as if it was in the foreground (well almost), so yes, you should just write a timer that stops the playback at a given time and it will be fired as expected.
Now to the second question: once you stop queueing things up, your app will be "frozen" until the user manually brings it to the foreground... So what you should do is start queueing audio data from the second file before the first one is done playing, and if you DO need to pause or stop, maybe a solution is to play 0 bytes (silence)?
I'm not actually sure this would be allowed in the App Store. An app is not allowed to execute at all in the background, with the exception of VoIP apps and push notifications.

idleTimerDisabled not working since iPhone 3.0

I have used:
[UIApplication sharedApplication].idleTimerDisabled = YES;
in a number of Apps developed and running under iPhone OS 2.x and never had any problems with it. They were clock apps so needed to run constantly and ignore the iPhone's idle Timer setting.
However, trying to achieve the same with a new App running OS 3.0 (and which needs to be deployed under 3.0 as it uses some 3.0 APIs) I've found the idle Timer to be either ignored or inconsistent.
My App plays music from the iPod library and when the music is playing it auto-locks regardless of the above setting. But once you unlock it, it then doesn't auto-lock again unless you play music again, in which case it locks again after the iPhone auto-lock time setting.
I'm amazed no-one else has come across this as I imagine it would affect a large number of Apps.
Just to clarify:
1. The above code is in ApplicationDidFinishLaunching
2. I know that the phone won't auto-lock when testing from xCode regardless of settings
If anyone has any thoughts I'd be very grateful...
Our app uses the MPMediaPLayer. We also had the idleTimerDisabled=YES code in the ApplicationFinishedLaunching, which works EXCEPT if untethered, and there is already a current nowPlayingItem which is left playing (or unpaused, if paused at app startup). Obviously this is all with the Settings -> General -> Autolock set to some timed value.
By adding idleTimerDisabled=NO, immedately followed by idleTimerDisabled=YES in one of the other bits of code AFTER we had figured out what bit of music we would get playing seemed to solve the problem. Just setting it to YES was insufficient.. and subsequent queries had always indicated the correct value (YES).. so it appears the Apple code ignores the setting of the value IF there is a current piece of music and that is not changed by your code.. but does notice a change of value.
This is all under iOS 3.0.
Even in 2015, using iOS 8.2, this bug is still alive and kicking.
Here's my solution, using XCode 6.2.
iPhone - phone goes to sleep even if idleTimerDisabled is YES
Basically, even now, in 2015, the only way to safely make sure that the device doesn't go to sleep is to repeatedly call a piece of code to keep the device awake.
-(void)callEveryTwentySeconds
{
// DON'T let the device go to sleep during our sync
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
}
Sounds like a bug, file with Radar - I am not too surprised this has not been seen much as there are probably not a lot of apps that try to lock the screen open and play music.
Having same issue. It does work when the device is plugged in. You can press lock button on top, and my NSTimer fires later and causes a vibrate. However if the device is not plugged in pressing the lock button puts the device to sleep. Any solution would be greatly appreciated.
iCodeblog posted about the idletimer, I said it didn't work, and the person who develops 'cute clock' was nice enough to reply. You have to do a hack, play a 1 second or longer silent sound every 10 or so seconds with NSTimer. This keeps the device awake even if the user hits the lock button.
I develop Seconds - Interval Timer for iPhone and iPod touch and I've had no end of trouble with this. The idea of my app is that people create timers based on a number of intervals where each interval can have it's own playlist or track played.
In iOS3 I had the problem that I couldn't disable the idle timer by just setting idleTimerDisabled = YES. In the end I came up with the same solution as Neil whereby I would periodically set it to NO, then immediately to YES again. This seemed to work.
I'm now updating the app to iOS4 (I know, iOS5 is just around the corner...) and now I have the opposite problem. If the MPMediaPlayer changes track before the idle timer reaches it's limit it gets reset. I've just tested this by creating an interval in my app that was 55 seconds, my auto-lock was set to a minute. At 50 seconds the screen dimmed as it prepared to lock, but at 55 seconds when the music changed it went back to full brightness and then didn't lock as it should.
Overall, the implementation of this seems flakey at best.