This post discusses using a Workout session to maintain background access. This is a very poor user experience as far as battery life goes but many apps are resorting to it for lack of better alternative.
Yeah, but I'd say that, because of the limited resources, continuously running a watchOS app in background hasn't been a supported use case from day one. Folks who are exploring how to achieve that goal might consider shifting the direction.
Also to be clear, using an active workout session in a non-workout app to extend the background execution time risks an App Review rejection.
This post discusses getting crashes on WatchOS 26 for exhausting CPU time with background HKObserverQueries, I too am seeing this despite calling the completion handler immediately and not running any processing code, is there any solution?
In that case, I can ony suggest that yo file a feedback report, as mentioned in the post.
If you already have one, please share so I can check the status. I see folks reporting this issue from time to time, but haven't yet seen them sharing their report.
Related to the scenario in point 2, are we also required to implement @WKExtensionDelegateAdaptor(ExtensionDelegate.self) var extensionDelegate and call tasks completed or is the completion handler in the observer sufficient?
Yes, in case your app is getting involved any background activity, you'd implement the handle method and set the task as completed. The SwiftUI equivalent is backgroundTask(_:action:). This is mentioned in Schedule and handle background refresh tasks.
In various places such as here I see discussion about if the app has a complication on the watch face and as such, it gets 4 updates an hour. This I find confusing... Pre-WatchOS 9 with ClockKit complications this makes sense, but since migrating to WidgetKit, I now get my widget extension woken for timeline updates and not my app. This is fine but not helpful for my use case and so has caused a regression in my app as I no longer get Watch app background updates from this... I hope I've made the differences clear here?
Having a complication on the active watch face adds the priority of the app, and impacts the execution time allocation policy on the system side, no matter the complication is based on ClockKit or WidgetKit.
Related to previous point, my understanding with this code try await healthStore.enableBackgroundDelivery(for: HKQuantityType(.heartRate),frequency: .immediate) is that although I ask for immediate, I'll be limited to 1 update an hour for heart rate on WatchOS, do I still get that update if I don't have a complication on the Watch face?
Yes. I am not quite sure if we document "1 update an hour" though. I'd expect that, without an active complication, you will get less than 4 updates per hour sometimes, especially when other apps that have higher priority (because they have an active complication and are used more frequently) need background execution time as well.
If I do have a complication on the active watch face, does that update have any impact on my complication WidgetKit timeline refreshes?
I don't think the WidgetKit complication timeline refresh is counted to the budget of the app's background execution time.
Overall I think there is a lot of confusion in the developer community with this topic
Indeed. An issue related to the background updates on watchOS can be hard to debug because it can happen randomly – The device situation, such as the battery level and other installed apps, impacts the background execution time allocation. Other than expecting that you can get an update in a period of time, having a fallback mechanism when you don't any update will be importnat as well.
Best,
——
Ziqiao Chen
Worldwide Developer Relations.