How to keep an Apple Watch app running when watch is charging - swift

I'm making an Apple Watch app to record user acceleration. Currently, the user configures the session length to record for, and using a HKWorkoutSession, the app records acceleration for that time period.
My issue: I want the user to be able to remove their watch and charge it in the middle of a long session. In debugging the watch on Xcode, when I place the watch on the charger, I get the messages:
Message from debugger: Terminated due to signal 9
Program ended with exit code: 0
And the debugger is no longer connected. After a short while, the HKWorkoutSession ends as well, and the app is no longer recording.
Looking at https://medium.com/#gohnjanotis/apple-watch-battery-level-charging-notifications-eb7d0797a4d8, and the statement "While on the charger it seems these background refresh tasks are paused altogether.", I'm not sure I understand the Watch app life cycle fully. Is it even possible to have an app continue running in the background when the watch is set to charge?
Would appreciate any advice on this. Cheers.

It's unlikely that watchOS background tasks work similarly to iOS, where an iPhone can for example do expensive Photos operations when the device is charging. Why not pause and resume the workout session?
The "Recover from Crashes" at the bottom of Running Workout Sessions | Apple Developer Documentation might be helpful.

Related

workout information send to phone live

I have created a heart rate monitor on the apple watch and that sends alerts to notifies you if your heart rate gets to low. After creating the app, I realized it does not run in the background. Is there a way to either force the app to run in the background on the watch or send the heart rate information to the phone?
I've investigated this, but don't have any practical experience (yet).
From what I understand, watch apps in watchOS3 can capture continuous heart rate updates with these conditions:
It's a full app (not just an extension).
The app starts a workout
Info.plist has the WKBackgroundModes key set
You'll need to either start the workout from the watch app, or if triggered from the companion iOS app you'll need to call start​Watch​App​With​Workout​Configuration:​completion:​ to start a workout session on the paired watch.
p.s. welcome to stackoverflow!

Measuring heartrate while Apple Watch is in sleep mode [duplicate]

I need to make an app that records heart rate data in near real time and send this data to a server as soon as possible.
First I took this approach: Watch os 2.0 beta: access heart beat rate
In fact it is working fine. There is new heart rate data in the HealthKit every five seconds. But now I have the problem that I can't sync that with a server.
My first approach was the Watch app. The watch was sending data to a server. That doesn't work because as soon as the screen turns black on the watch, it stops sending.
My next approach was to query the HealthKit on the iPhone every five seconds for new data. This works, as long as the app is in foreground.
Then I saw that there's some kind of background functionality that watches the HealthKit itself and revokes the app from background and you can do something.(enableBackgroundDeliveryForType) This doesn't seem to work for heart rate (the Apple Documentation says for things like steps this doesn't work, I guess heart rate is one of those).
I'm stuck now. Do you know how to it? I would need some background task that is executed every 5-10 seconds on the iPhone. That seems to be impossible
UPDATE
As noticed by #BootMaker, Apple made background mode available for HKWorkout apps in WatchOS 3, so it's working now. You have to run a HKWorkoutSession and this will keep your heartrate delivery in real time even when the app is in the background (dark screen on watch)
The closest you are going to be is while the watch app is open.
Why I'm stating this?
There are two HealthKit's Database (one at the iPhone and another at the Apple Watch). When they sync is arbitrary and decided only by the O.S.
The closest you are going to be to real time is when you don't have any password locking your screen in iPhone or Apple Watch.
Either way, there's no guarantee that the sync will happen every time a new measure is added to Apple Watch's HealthKit
The only way to force the Heart rate sensor into working in real time is via workouts or observer while your Apple Watch app is in FOREGROUND.
Background delivery is NOT available for Apple Watch apps.
Watch OS 2 request the sensor to measure automatically (in background) every 10 minutes minimum.
There's no other workaround, if you need real time for longer periods, or while the user is not using your app, you will need to use an specialized wearable.
If anyone still need to get heart rate or other data in real time. Use this solution:
Develop an apple watch app/extention
In watch app, using HKHealthStore, HKWorkoutConfiguration, HKWorkoutSession, HKLiveWorkoutBuilder to create an Workout. After create workout, your watch app will get heart rate in real time.
Using watch kit connection with WCSession to send data to iPhone app.
Enable background mode both in apple watch and iPhone.
I tested, even app terminated, we can still get heart rate (I used Local notification for posting heart rate data for debugging)

Why does my iPhone App continue in the background?

I wrote my first iPhone App, and managed to get it into the App store. I later discovered a bug that happens on a real device but not on my emulator. I have committed a fix (changed plist to prevent app running in background), but I don't really understand why it happened.
My App allows users to record a sound-byte, however while they are recording they can use the iPhone home button to move the app to the background, and then it can keep recording forever if they don't restart the phone or the app does not crash.
My impression from everything I have read, is that this should not happen as you have to ask for background audio specifically if you want to do this, but now it appears to me that you have to ask specifically to disable it.
Could anyone explain this to me?
The iOS App lifecycle is described in Apple's iOS App Programming Guide.
The App is given the opportunity to save data and otherwise stop things that don't need to be running, before being suspended. You can request extra time doing this by using beginBackgroundTaskWithExpirationHandler:.
If you want your app to stop doing its "normal thing" when it is put into the background then you need to detect the App state transition and stop it yourself.

Does iOS 4 make “Real Multitasking” available to 3rd party developers?

Ever since the first beta came out I’ve been trying to find out if “real” multitasking is possible — i.e. can you put a program in the background and have it hang on to a network connection indefinitely?
I’m thinking about IM or IRC apps, for example. I’ve compiled an app myself on iOS 4, and without changing a thing it appeared to stay running in the background, but for all I know it was just suspended to memory.
The docs say the best you can do is request up to 10 minutes, but in the developer presentation they showed off Skype sitting in the background and then notifying the user that a call was coming in. Does anyone know for sure how this all works?
It appears the answer is no. The API for Skype is a very special case, called the "voip" mode, and requires special behavior, such as marking the socket in use for VoIP.
You can receive alarm notifications in the background (such as time passed). The amount of time you are in the background running state is severely limited by the OS.
Android's background model is complete and in many ways much nicer.
Apple has a guide named "Supporting Multitasking In Your Applications" which you should be able to locate.
Apple's iOS 4 developer docs outline this all very clearly.
When your app is closed or switched away from, it is almost immediately "suspended", meaning the OS freezes the app's state. When the user switches back to your app, your code keeps running just where it kept off. You don't need to add any code to your app to do this, just compile it against OS 4.
The above is true in most cases. There are two reasons the "suspended" model may not apply:
1) If the device starts to run low on memory, the OS will start terminating suspended apps that haven't been switched to in a while, without warning. This is why it's in your best interest for your app to remember it's state as well, so if your app is terminated, then re-opened, the user doesn't really notice because it still returns to right where they left off.
2) Your app uses one of the "background" APIs. These are for audio playback, VoIP services, or location services. In this case, your app is allowed to continue running in the background but only has access to those APIs. Additionally, your app can designate certain long-running tasks as "background tasks" that need to be completed before the app is suspended or terminated, like uploading pictures to Flickr or rendering a video, etc.
The "background task" method doesn't cover pinging servers indefinitely, as there is a time limit for the task, after which it will be forcibly halted. Apps that need that sort of functionality are expected to implement push notifications, just as before.
That should clear this up. All in all I think it's a pretty elegant solution to multitasking on a mobile device.
iOS 4 applications can either be running or suspended. The operating system will try to keep as many requested applications as possible in memory, while all other applications are suspended.
Applications that run in the background can access features such as navigation, audio, and VOIP (but NOT instant messaging). So it looks like you might be out of luck.
-- PC World Multitasking on Apples iPhone 4
It is possible for apps to request background time. Read the docs. I would say it iOS is "controlled multitasking".
You can create a long running background task, I believe these can include networking features. Just have to set the background task flag on the work block.
https://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
the OS can limit exactly how much time you get though... it will tell you when your time is up giving you a chance to cleanup nicely.
iOS 4 has "real" multitasking to some extend. There are two things to consider:
The UI event loop is single tasking. So only the front app executes on the UI event loop. Not a big deal: detach your main code form the UI event loop (maybe you need to redesign your app).
The OS "may" terminate your app if some criteria are met (e.g. low memory).
Currently one of these criteria is that execution time is limited to 10 minutes (real time not cpu time). However I expect this to change and see better criteria for background app termination (I hope to).
Apart from this you can have timers (event loops) in background.
There is no real multitasking in iOS 4.2 even. because apps will only be allowed to finish the task related to states..for small interval of time and then it will be in suspended state.. If you will set background task for long interval of time then... it will behave unexpectedly like no method will be called when you will try to run the app from anywhere..
You may be interested in this blog post that outlines how "multitasking" works in systems such as iPhone OS 4 and Android.
in fact u can do this, although it's not allowed by Apple. u gotta set up a toolchain in ur mac and use some unofficial SDK...
check http://code.google.com/p/iphone-backgrounder/ for more information
You should use the Push Notifications framework for the feature set you are creating!

NSTimer callbacks while iPhone application is inactive

This question seems to be the essence of several others on this forum. I believe that it is possible for the active iPhone application to continue running, and specifically, to continue receiving timer call-backs, after it has entered the inactive state (either through the idle timer kicking in the screen lock, or through the user pressing the hardware lock button).
The documentation specifically says that while an application is inactive, it is executing, but not dispatching incoming events (I'm not giving a link because I'm jumpy about NDA - should I relax about that? Is this whole post a breach? sigh).
Also, two answers by user "Ambr Str" directly state that it is possible to continue receiving timer call-backs, and he supplies a snip of code to achieve it (I can't link to this because I'm a new user, sorry - search for the question: "What happens to an iPhone app when iPhone goes into stand-by mode?" to find his answer).
I've tried to create my call-backs as he suggests, but once my application becomes inactive, the call-backs cease firing.
I've just noticed that while the iPhone is plugged in, if the application becomes inactive (due to idle time out or me pressing the sleep button), call-backs do continue to occur - perhaps I should get my users to carry a battery pack with them ;-)
There is a good answer to this question on Apple's forums. Search for "Timer" and "Eskimo" (the helpful chap who provides the answers).
In brief, shortly after the application becomes inactive, the phone really does go to sleep. The only way to prevent this is to be playing some audio (or for some audio to be playing in a background application). While audio is playing the phone will not sleep, and your application continues to be run.
It is suggested that playing stay awake audio is a hack, and that you shouldn't do it if at all possible. I think in my application (which performs audio playback interspersed with silent periods), the approach is valid, if not ideal!
I have an app. which includes an embedded webserver. I'm planning to offer an option of disabling auto-sleep IFF the server is turned on, AND the device is on power. So you might consider checking the batteryState property of UIDevice. So if batteryState != UIDeviceBatteryStateUnplugged, go ahead and disable idle timer. (note: the docs say that UIDeviceBatteryStateUnknown will be returned when in simulator.)
You'll also want to listen for UIDeviceBatteryStateUnplugged notifications and set batteryMonitoringEnabled appropriately.