9

I know iOS allows background tasks to run and, for example, continue to receive location updates, but is it possible to do this in a watch app? In Xcode 9.3, I have configured my app for "background modes" and selected location, and that has created for the WatchKitExtension's an Info.plist, an entry for "Required background modes" of "App registers for location updates".

But my watch app still suspends when the screen turns off, and when it is in the dock.

The App Programming Guide for watchOS, however seems to exclude the possibility of running in the background to receive location updates as it only allows background processing for four classes of activity:

  1. Background App Refresh Tasks. Use a WKApplicationRefreshBackgroundTask object to ...
  2. Background Snapshot Refresh Tasks. Use a WKSnapshotRefreshBackgroundTask object to update ...
  3. Background Watch Connectivity Tasks. Use a WKWatchConnectivityRefreshBackgroundTask object to receive data sent by your iOS app ...
  4. Background NSURLSession Tasks. ...

Other posts to SO indicate it's not possible, but proving a negative is difficult, so I'm asking again:

Am I "flogging a dead horse" by trying to keep the watch App operating in the background for receiving location updates, or is Xcode is making promises that WatchOS won't deliver.

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
alan.raceQs
  • 411
  • 4
  • 11

2 Answers2

9

I'm delighted to be able to report that the horse I have been flogging for the past two weeks was not dead after all!

I have discovered an additional state in which my watch app will continue to run in the Background which does not require HKWorkoutSession.

These settings did the trick:

locationManager.allowsBackgroundLocationUpdates = true

and in watchKitExtension info.plist:

set UIBackgroundModes (Required background modes) to location (App registers for location updates)

And I repeat: I am NOT using healthKit

Now my app continues to run even when the screen is off and when the app is out of the Dock.

Sailor Al
  • 797
  • 1
  • 7
  • 20
  • Wait a second: did you actually receive background information while the app is not on the foreground? I've been trying this, even using the `allowsBackgroundLocationUpdates` you mentioned, to no avail. As @Dávid Pásztor mentions below, even Apple says this shouldn't be possible. – francisaugusto Feb 05 '18 at 19:20
  • Yes, it continues to receive and process location updates when fully in the background, either out of the Dock or with the screen off. So much so, that I have had to add a user input to switch off the location updates to fully kill the app! I'm still nervous that I have may have found a back door that Apple will slam when I go to publish. Give it a go yourself and – Sailor Al Feb 06 '18 at 20:26
  • I will try! In fact, I only need to use it with the `requestLocation()` call. I need it to get my location in order to get the correct update for my app. I tried a few times, and the background process hangs there. – francisaugusto Feb 06 '18 at 20:34
  • I suspect that it won't work with requestLocation as your app will have to be in the foreground to be able to issue the command. – Sailor Al Feb 06 '18 at 20:45
  • That's bad for me, because I don't need to keep the app receiving locations - I suspect that this might drain the battery quite soon. I need it to grab the location once every hour. – francisaugusto Feb 07 '18 at 06:34
  • It works beautifully, even with `requestLocation()`! I schedule my application refresh so that i gets a single location, and it works beautifully! The reason why it didn't work before was because I forgot that location retrieving is asynchronous, and I was calling `setTaskCompleted()` before the location was ready. – francisaugusto Feb 08 '18 at 19:01
  • 1
    Have a gold star for perseverance! So what's all this talk about it not being possible? Have had your app approved for publication? – Sailor Al Feb 08 '18 at 20:08
  • No, I am still a bit far from that. But I can't see why it won't be approved, as they specifically introduced this with watchOS 4. :) – francisaugusto Feb 08 '18 at 20:09
2

No, it is not possible.

As the WatchKit Programming Guide clearly states, WatchKit apps cannot use background execution except for 3 use cases:

  • Network operations using URLSession
  • Playing audio using WKAudioFilePlayer or WKAudioFileQueuePlayer
  • Run a workout using HKWorkoutSession

You cannot receive location updates in the background, according to the WatchKit Programming Guide, that should be done in the iOS app that is connected to your watchOS application.

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • Maybe I'm, asking the wrong question, but it's clearly possible. There are apps that do continue to get location updates when the screen is off or when in the Dock. Both Strava and Nike+RunClub record your track when the phone is left at home. I just installed them on my AW2 and can positively confirm that. – alan.raceQs Dec 20 '17 at 21:14
  • They are workout apps and use a `HKWorkoutSession` object to be able to run in the background. You can receive location updates during a workout session, but if your app isn't a real workout app it will likely get rejected from the AppStore for using `HKWorkoutSession` just to get location updates. – Dávid Pásztor Dec 20 '17 at 21:16
  • Except for native apps. Native apps have "special permissions" and they can stay in foreground even if they're not running a workout session or playing audio. – Ramy Al Zuhouri Dec 20 '17 at 21:27
  • Do you mean system apps? There are only native apps for `watchOS`, you can't use frameworks like Cordova to write non-native apps for `watchOS`. If you do mean system apps, I don't see the relevance of that, since this question was clearly not asked by an Apple developer making a system app for `watchOS`. – Dávid Pásztor Dec 20 '17 at 21:29
  • Yes, I meant system apps, and I pointed it out to make clear why some apps (e.g. timer) can run in the foreground indefinitely. – Ramy Al Zuhouri Dec 20 '17 at 21:33
  • You are correct, I'm not an Apple developer! My app is for sailboat racing which, most participants would agree, definitely is a workout! Any suggestions how I can test the possibility of Apple rejecting my app in advance? (I seem to have acquired two ID's, I'm also user3047912 who posted the original Q) – Sailor Al Dec 20 '17 at 21:44
  • @StarTraX there’s no way to test that. If you follow Apple’s programming guide and human interface guidelines, your app will get accepted, but if you break any of the guidelines, you risk getting your app rejected. However, no one can answer for sure except Apple. – Dávid Pásztor Dec 20 '17 at 21:47
  • I know this is a subsequent question, but it’s still sort of on topic. When my app is in the dock, (without implementing any background modes or HealthKit stuff) it continues to run until I scroll the app out of view. When I scroll the Dock view to display my app again, it resumes running. I determine this as my app displays the time. So are there two states of an app in the Dock: 1) While displayed and 2) while not displayed ? – alan.raceQs Dec 22 '17 at 00:59
  • The fact that your app displays its view in the dock doesn't mean it's actually running in the background. `watchOS` calls some methods to let your app update its snapshot displayed in the Dock using a [WKSnapshotRefreshBackgroundTask](https://developer.apple.com/documentation/watchkit/wksnapshotrefreshbackgroundtask). – Dávid Pásztor Dec 23 '17 at 12:28
  • @DávidPásztor: Is it possible to keep workout all the time?? – Abhishek Thapliyal Nov 15 '18 at 11:51
  • 1
    @AbhishekThapliyal unless you are actually developing a workout app, no. First of all, your app would get rejected if you used workout mode for a non-workout app just to be able to run it in the background. Secondly, using workout have results in a serious battery drain, especially when not used correctly. – Dávid Pásztor Nov 15 '18 at 12:10
  • @DávidPásztor: Actually i want monitor Heart Rate all the time(per minute) with Health Kit, So i want it to be run all the time, Can it be possible?? – Abhishek Thapliyal Nov 15 '18 at 12:13
  • @AbhishekThapliyal yes, it is possible, but then you kill your battery within 6 hours. We do this current within our company. – SamIAm Aug 29 '23 at 16:08