HealthKit

RSS for tag

Access and share health and fitness data while maintaining the user’s privacy and control using HealthKit.

Posts under HealthKit tag

200 Posts

Post

Replies

Boosts

Views

Activity

HealthKit data - Is HKStatisticsCollectionQuery slow?
Hi, I am using HealthKit for the first time. I am using HKStatisticsCollectionQuery. I am running my code iOS 17 on a physical iPhone. It takes several seconds to query data, for example 1 day worth of heart rate at 1 minute resolution. I changed the resolution to 1 hour, expecting it to be faster, but it's pretty much the same… I have been following the official documentation and sample code. I also compiled in Release, but that didn't really help for HKStatisticsCollectionQuery. I quickly looked with Instruments, the app is spending a lot of time in decoding data with NSXPCDecoder. Is there a way to speed data retrieval? Or this is "expected" latency?
2
0
1.3k
Oct ’24
Workout Effort Scores
Is there anywhere that describes in detail how third party workout apps can use the new effort score functionality? I can't see much in the documentation or any of the WWDC videos. In particular it would be useful to know if an effort score is automatically calculated for workouts created with third party apps? It doesn't seem to happen but some people say it takes weeks / months before watchOS starts calculating it for third party apps. If it doesn't happen automatically then how can the app set it? I tried the new relateWorkoutEffortSample API but that didn't work for me (see https://developer.apple.com/forums/thread/763539). If I could get it working then how should I determine a default effort score based on the workout metrics? Is that something that the app should do? If so then it would be good to be consistent with watchOS so some idea of how that is calculating effort scores would be useful. Sorry for all the questions, especially if there is an article in the documentation or a video that I have missed.
4
0
2.3k
Oct ’24
Missing manual - Training Load, .estimatedWorkoutEffortScore, .workoutEffortScore - Where are the Apple RPE CR-10 scale docs?
Apple is using the RPE scale for workout effort scores. This stands for the Rate of Perceived Exertion. They're specifically using the CR-10 scale, at least from what I can tell by saving values to HealthKit. They only accept value between 0 and 10. Has anyone been able to find a scientific or academic paper on how they have chosen their different effort breakouts? Right from the Fitness app on iPhone and Activity app on Apple Watch: 1-3 Easy 4-6 Moderate 7-8 Hard 9-10 All Out There is zero documentation on these new types, which makes it difficult for workout recording apps to properly and appropriately save this new data type. Sure, we can use the Apple apps as a reference, but since there isn't a built-in Apple SwiftUI sheet to present this data, and no references to academia to point our users to, our solutions would just look the same. FB15315876 - Documentation / HealthKit: Publish documentation about .workoutEffortScore and .estimatedWorkoutEffortScore FB15316109 - Documentation / HealthKit: Add documentation to .estimatedWorkoutEffortScore and .workoutEffortScore that you can't save those samples via the save API and that they must be related and let that API save the sample FB15316251 - Documentation / HealthKit: Add documentation for acceptible values of .estimatedWorkoutEffortScore and .workoutEffortScore - don't rely on a runtime error! Apple missed making an enum for all third party developers this year.
0
1
744
Oct ’24
How to add "Estimated Time in Each Heart Rate Zone" info to my custom HKWorkout when viewed in Apple Fitness app?
Hello, I’m currently developing a fitness app for watchOS that lets a user to manually set a desired heart rate target zone (enter numbers representing the lower and upper boundaries) and start a workout (right now it’s only “Other” type). After that my app monitors user’s heart rate and alerts them when they’re out of zone. When user ends the workout, the info about this workout appears on “Fitness” iOS app, and user can see the workout data like Workout Time, Active and Total Calories, Avg. Heart Rate. Also user can see Heart Rate chart with info how their heart rate was changing during a workout (see the Figure 1). Now to the question. When user clicks “Show More” button above the Heart Rate chart, they can see the same Heart Rate chart and another one, with Post-Workout Heart Rate (see the Figure 2). But there is no “Estimated time in each heart rate zone” as one can see in the workout’s details that were recorded from Apple’s workout (watchOS “Workout” app, for a workout of “Other” type as well). Please see the Figure 3. The question is: is it possible to add “Estimated time in each heart rate zone” to workout recorded via my third-party app so it would look like on the Figure 3 in "Fitness" iOS app, and if it's possible, what steps should I undertake to implement this ? Thanks in advance! I posted the screenshots in the replies to the post, because otherwise I was not able to submit a post ("sensitive language" warning, I suspect it's because of the ids in the attached screenshot's urls)
2
0
1.3k
Oct ’24
internal healthkit error: "Unable to invalidate interval: no data source avallable"
we are seeing what appears to be an internal healthkit error appearing in our app.  not sure if it's connected, but we've mostly seen it reported on devices running ios 16.  even though our app's primary language is japanese, and in all reported occurrences the app was running in japanese, the error message itself appears in english.  searching the error string on the web yields surprisingly few results (including only two mentions on this forum that i could find, neither of which seemed relevant).  this would seem to suggest that it's coming from something deep inside healthkit, since the error message is not localized.  in all reported cases, the user had recently upgraded to a new iphone.  in most cases, the problem only occurs on the new device even though everything had been working correctly prior to the upgrade.  the error occurs when the app is unable to read step count data from healthkit. we have confirmed that the app has been granted access permissions to all health data via os settings.  we've also tried having the user toggling those settings off, then back on, rebooting the device, deleting and reinstalling the app, etc., to no avail. the error message is "Unable to invalidate interval: no data source avallable." we'd appreciate it if anyone can shed more light on this issue. thanks!
4
3
1.9k
Oct ’24
HealthKit permission sheet appears every time for some users - bug?
The HealthKit permission sheet is showing up every time the app opens for a few users of my app. It doesn't matter what action they take in the sheet. I have had them try toggling the permissions from the HealthKit system settings but that did not happen to fix the problem. Has anyone experienced this problem or know a fix? Its affecting a few users of my app. I haven't been able to find what in my code could be doing this, I suspect its a bug on HealthKit's side for specific users. I can't find anyone reporting this problem elsewhere so I have to assume its my fault, but the docs clearly state that the permission sheet will only be presented once.
8
9
2.2k
Oct ’24
visionOS App Not Receiving Latest Heart Rate Data from HealthKit
Hello everyone, I'm developing an app for visionOS that utilizes HealthKit to query heart rate data. However, I'm encountering an issue where the app doesn't retrieve the latest heart rate values. Specifically, it fails to get live heart rate data even after the data has been saved to the Health app. The readings my app displays are outdated and do not match the current values shown in the Health app. Here's what I've tried so far: Fetching Heart Rate Samples: Used HKSampleQuery and HKAnchoredObjectQuery to fetch the most recent heart rate samples. Despite this, the data retrieved is still not up-to-date. Checking Permissions: Ensured that all necessary HealthKit permissions are granted. The app has authorization to read heart rate data and write workout data. My questions are: Is there a known issue or limitation with HealthKit on visionOS that prevents apps from accessing the latest heart rate data? Are there additional steps or configurations required to access live heart rate data in visionOS apps? Has anyone successfully implemented live heart rate monitoring on visionOS, and if so, could you share how you achieved it?
0
0
534
Sep ’24
HealthKit bugs related to new workout effort score - heart rate samples take forever to fetch, Health app displays invalid data
I am encountering issues on my device running iOS 18 that fetching heart rate samples associated to a given workout is very slow. Like 10+ seconds slow. This is unacceptable and unexpected. In producing a video to attach to a feedback, I also observed that Apple Health app displays incorrect information if a workout effort score is associated to a workout. In this image, you can see the Health app bug: Total Resting Energy != Estimated Workout Effort Score Here is the same workout after I delete the workout effort score using the Apple Health app: Can anyone else see if attempting to view 'heart rate' data within the workout summary in Apple Health is unbearably slow if that workout also has an effort score associated? My steps: Record workout (Apple Activity app on watchOS) Associate effort score View the workout on Apple Health (iOS) Attempt to view it's heart rate samples Observe very slow loading times Observe the incorrect cell label and value and disappearance of resting energy cell data Remove/disassociate the effort score from the workout by tapping the workout effort row, and swipe to delete the value. Navigate back, navigate back, and then go into the workout detail again At this time the UI fixes itself, but the loading of heart rate data is still super slow FB15269657 - HealthKit: Sample query to fetch heart rate samples associated to a workout is taking over 10 seconds - computing 'time in heart rate zone' FB15278790 - Health: Workout summary 'Total Resting Energy' label has value of 'Estimated Workout Effort Score' for a value, pushed view shows empty
0
0
772
Sep ’24
Wake-up detection with HealthKit
Hello HealthKit Experts & Enthusiasts! I am building an app called one sec which forces people to take a deep breath before they can use social media apps (it’s using Shortcuts Automations for that). One important feature of one sec is the Good Morning Countdown: For a specified time after waking up (e.g. 30mins) selected apps are blocked completely. This helps to start the day screen-free. They way it works is, the user grants access to read HKCategoryTypeIdentifier.sleepAnalysis data. I have implemented a HKObserverQuery and enableBackgroundDelivery in order to be informed whenever new HKCategoryTypeIdentifier.sleepAnalysis becomes available. I noticed that when I have my device connected to Xcode, this works as expected. However, when I quit the app and launch it from my Home Screen, my observer query is not informed about new sleep data (except when my app is running in foreground). Any ideas? Furthermore, I have noticed that sometimes sleep data is provided delayed to HealthKit, many minutes (sometimes even longer) after waking up, no sleep samples are to be found in the Health app. Of course, for my app it is crucial to get accurate + timely so apps can be blocked accordingly. Is this an issue that the Apple Watch first needs to send the samples to the phone? Thanks a lot for your help!
1
1
953
Sep ’24
Overlapping Segments and Duplicate Start Times in Workout Data
Hello, We're encountering overlapping segments and discrepancies when analyzing running/workout data for a 5-mile run. The expected splits for the run are: 8:39 9:06 8:30 8:39 8:43 0:08 However, the raw data includes segments where start times begin before the previous segment ends, and there are duplicate start times. Below is a sample of the raw data: "startDate": "2024-09-09T19:32:00.308-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T19:37:56.135-0400" }, { "startDate": "2024-09-09T19:32:00.308-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T19:41:08.476-0400" },``` // Here's an example of where the second segment start time falls in side the first segments startDate and endDate "startDate": "2024-09-09T19:54:22.658-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T19:59:41.215-0400" }, { "startDate": "2024-09-09T19:58:44.624-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T20:07:23.216-0400"
8
0
1k
Sep ’24
HKLiveWorkoutBuilder only reporting heart rate - No other measurements
I'm using Healthkit with the following H/W specs: Apple Watch, series 8, OS: 10.6.1 (21U580) iPhone 11 Pro, OS: 17.6.1 Mac Studio M1 Xcode ver: 16.0 (16A242d) I am trying to get Apple Watch to report heart rate, HRV, respiratory rate, and body temperature using Healthkit's HKLiveWorkoutBuilder implementing HKLiveWorkoutBuilderDelegate's workoutBuilder method. However, the only reported value that is found from the workoutBuilder method's collectedTypes (a Set of HKSampleType objects) is HKQuantityTypeIdentifierHeartRate. Nothing for HRV, respiratory rate, or body temperature. All entitlements are set up, the plist filled in, and capabilities in place. Not sure why only the heart rate is reported from the watch but nothing else. I've scoured StackOverflow, Apple developer forums, even ChatGPT but none of the solutions work. Any help most appreciate! The model code is: import Foundation import HealthKit class WatchModel: NSObject, HKLiveWorkoutBuilderDelegate, HKWorkoutSessionDelegate { private let healthStore = HKHealthStore() private var workoutSession: HKWorkoutSession! private var workoutBuilder: HKLiveWorkoutBuilder! override init() { super.init() requestAuthorization() startWorkoutSession() } private func requestAuthorization() { let heartRateType = HKQuantityType.quantityType(forIdentifier: .heartRate)! let respiratoryRateType = HKQuantityType.quantityType(forIdentifier: .respiratoryRate)! let HRVRateType = HKQuantityType.quantityType(forIdentifier: .heartRateVariabilitySDNN)! let temperatureRateType = HKQuantityType.quantityType(forIdentifier: .bodyTemperature)! let healthDataTypes: Set = [heartRateType, respiratoryRateType, HRVRateType, temperatureRateType] healthStore.requestAuthorization(toShare: healthDataTypes, read: healthDataTypes) { (success, error) in if !success { print("Authorization failed") } } } func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) { } func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: any Error) { } func workoutBuilderDidCollectEvent(_ workoutBuilder: HKLiveWorkoutBuilder) { } func startWorkoutSession() { let configuration = HKWorkoutConfiguration() configuration.activityType = .other configuration.locationType = .indoor do { workoutSession = try HKWorkoutSession(healthStore: healthStore, configuration: configuration) workoutBuilder = workoutSession.associatedWorkoutBuilder() workoutBuilder.delegate = self workoutBuilder.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: configuration) let dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: configuration) let respiratoryRate = HKQuantityType(.respiratoryRate) dataSource.enableCollection(for: respiratoryRate, predicate: nil) let bodyTemp = HKQuantityType(.bodyTemperature) dataSource.enableCollection(for: bodyTemp, predicate: nil) let hrv = HKQuantityType(.heartRateVariabilitySDNN) dataSource.enableCollection(for: hrv, predicate: nil) workoutSession.delegate = self workoutSession.startActivity(with: Date()) workoutBuilder.beginCollection(withStart: Date(), completion: { (success, error) in if let error = error { print("Error starting collection: \(error.localizedDescription)") } }) } catch { print("Failed to start workout session: \(error.localizedDescription)") } } func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>) { print("collected types: \(collectedTypes)") for type in collectedTypes { if let quantityType = type as? HKQuantityType { if quantityType == HKQuantityType.quantityType(forIdentifier: .heartRate) { if let heartRateQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let heartRateUnit = HKUnit(from: "count/min") let heartRateValue = heartRateQuantity.doubleValue(for: heartRateUnit) print("heart rate: \(heartRateValue)") } } if quantityType == HKQuantityType.quantityType(forIdentifier: .heartRateVariabilitySDNN) { if let hrvQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let hrvUnit = HKUnit.secondUnit(with: .milli) let hrvValue = hrvQuantity.doubleValue(for: hrvUnit) print("HRV: \(hrvValue)") } } if quantityType == HKQuantityType.quantityType(forIdentifier: .bodyTemperature) { if let bodyTempQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let tempUnit = HKUnit.degreeCelsius() let tempValue = bodyTempQuantity.doubleValue(for: tempUnit) print("body temp: \(tempValue)") } } if quantityType == HKQuantityType.quantityType(forIdentifier: .respiratoryRate) { if let respRateQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let respRateUnit = HKUnit(from: "count/min") let respRateValue = respRateQuantity.doubleValue(for: respRateUnit) print("breathing: \(respRateValue)") } } } } } }
6
0
1.2k
Sep ’24
recoverActiveWorkoutSession() inaccurate for paused sessions
When a workout session is being recovered, if it is paused, the elapsed time will be incorrect. It will seem like that workout never was paused. The recovery works fine if the workout was never paused. Steps to reproduce: Implement recoverActiveWorkoutSession Start workout Pause session and print the elapsed time Stop simulator / cause crash When recoverActiveWorkoutSession is called the elapsed time will not equal the elapsed time when the session was paused. Here is my implementation. I haven't seen any examples online. guard let recovered = try? await healthStore.recoverActiveWorkoutSession() else {return} self.session = recovered self.builder = recovered.associatedWorkoutBuilder() self.session?.delegate = self self.builder?.delegate = self self.builder?.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: recovered.workoutConfiguration) self.sessionState = recovered.state
1
0
919
Sep ’24
What's the correct way to check for unavailable API?
I ran into a problem recently with my production app and an update for iOS 18. In this example I was using a new API added to the RC candidate of iOS 18.0, using this API as an example, I couldn't find a satisfactory way to avoid crashing on iOS 18.1 where the API was not available. I had plenty of users running the iOS 18.1 Beta and ultimately it's my fault if a version of my app did work, and then didn't after an update.... This code causes a crash on iOS 18.1 beta as the .appleSleepingBreathingDisturbances API doesn't seem to have made it's way into the beta: if #available(iOS 18.0, *), #available(watchOS 11, *) { healthKitTypesToRead.insert(HKQuantityType.quantityType(forIdentifier: .appleSleepingBreathingDisturbances)!) } I tried this but it still crashed on 18.1: if #available(iOS 18.0, *), #available(watchOS 11, *) { if let newQuantity = HKQuantityType.quantityType(forIdentifier: .appleSleepingBreathingDisturbances) { healthKitTypesToRead.insert(newQuantity) } } In the end the only way I could resolve this was the following: if #available(iOS 18.1, *){ // Do nothing } else if #available(iOS 18.0, *), #available(watchOS 11, *) { if let newQuantity = HKQuantityType.quantityType(forIdentifier: .appleSleepingBreathingDisturbances) { healthKitTypesToRead.insert(newQuantity) } } This seems like a poor solution and I'll have to ensure I release a new version of the app once iOS 18.1 has the available API added to enable support for the feature. How could I have checked availability for this API correctly without causing the app to crash? I'm asking this question more as a Swift language feature rather than issue with the specific API as I'm sure that will get resolved soon anyway. Thanks
4
1
1.5k
Sep ’24
Regular step count fetch and upload to API
Hello all, I am quite new to iOS and Swift, and before venturing further, I feel it's better to ask for advice. I have build a Type I diabetes simulator running as a NodeJS application on a server. The clients authenticate via a browser using Fitbit/Google oauth2, set up a virtual patient, then take care of the patient 24/7. The app imports the users steps and heartrate, as these influence the blood sugar variations. (https://cgmsim.com) I designed a companion app with Expo, adding high/log blood glucose alerts with push notifications. If the user doesn't have a Fitbit tracker or doesn't use Google Fit, I'd like to send their HealthKit step counts to the backend. (Using sensor data directly in Android). It works using Expo's Background Fetch and TaskManager, but the uploads from the iOS device are very irregular. I set up silent push notifications from the backend to wake up the app in the background and trigger the step count upload. It works, but it is not reliable enough. I now wrote my first local native module for iOS, where a HKObserverQuery listening for new step events, making the upload and sending the count to the JS for rendering. I used enableBackgroundDelivery and BackgroundTask for uploading the results. All the entitlements and Info.plist entries should be ok. Still my app works well only in the foreground, and not upload at all happens when in the background. As we all do, I asked Claude, and it assured me th app should work. I have doubts though, as I noticed how strict iOS is about executing background tasks. So... should I even expect this to work ?
1
0
1.2k
Sep ’24
Workouts, activity rings, samples and more not syncing across devices running iOS 18 RC and watchOS 11 RC
I noticed last night that workouts I have been recording on my main carry device running 17.6.x have not been syncing to my beta devices running iOS 18 RC, iPadOS 18 RC and watchOS 11 RC. All devices are using the same Apple Account and I have iCloud enabled for Health data. The iPad running the RC has the syncing enabled in Profile. Is anyone else experiencing health data not propagating to the 18.x devices? Some of data exists on all devices but not all. For good measure I left the device unlocked on the health app last night for a long period of time to let it do its thing. This morning the data still hadn't propagated. I disabled and reenabled the synchronization on my iPad having chosen to delete all samples when disabling it. Hopefully all of my data dating back to the first Apple Watch in 2014 restores. FWIW my data set according to iCloud settings my health dataset is just shy of 650 MB. FB15102443 - Health / HealthKit: Workouts, activity rings, sample data, and more not syncing via iCloud to 18 RC device
0
0
673
Sep ’24
Health Export not complete
Good evening, when I use the automatic export feature from my iPhone, it successfully exports data. When reading the Export.xml file it is dispayed completely, with about 3 mio lines. When I check the file I see, that a lot of data is missing. E.g. the iPhone dispays the heart rates for several exercises (from last year), which don't have any correspondence in the export.xml file. Current exercises have. I am a developer myself and parsed all files without any error. My iPhone has enough free space (200GB or so) and iCloud has more than a TB free. Internet is connected via 1GBit line, WLAN with 800MBit and everything runs smooth. I would like to get a COMPLETE export of all the health data, without having to write a program on my own to accomplish this. Thank you. /C
0
0
526
Aug ’24
I have rejection issues: Healthkit
Like my post title? I'm having issues getting my app accepted by the app store. I keep getting the message: Guideline 2.5.1 - Performance - Software Requirements Your app's binary includes references to HealthKit components, but the app does not appear to include any primary features that require health or fitness data. I don't have healthkit implemented anywhere in my app. I sifted through my app and: Healthkit is not implemented in my infoplist There are no HK imports My app doesn't reveal any references to "Health Kit" when I do a project wide search. The only thing I can think of is that there's an issue with my use of firebase. I'm wondering if I somehow inserted healthkit functionality in to firebase accidentally. Has anyone else had this problem before? If so, how did you solve it? Also. How do you rid of healthkit functionality or references to healthkit within firebase?
4
0
870
Aug ’24
BGTaskScheduler with
I’m trying to use BGProcessingTaskRequest to fetch step data in the background and send it. However, when I combine BGProcessingTaskRequest, HKObserverQuery, and healthStore.enableBackgroundDelivery, the results sometimes return zero. When I don’t schedule the BGProcessingTaskRequest, the data retrieved using HKObserverQuery and HKSampleQueryDescriptor is correct. // Register Smart Walking Sync Task func registerSmartWalkingSync() { #if !targetEnvironment(simulator) BGTaskScheduler.shared.register(forTaskWithIdentifier: BGTaskIdentifier.smartwalking.rawValue, using: nil) { task in guard let task = task as? BGProcessingTask else { return } self.handleSmartWalkingSync(task: task) } #endif } func scheduleSmartWalkingSync(in seconds: TimeInterval? = nil, at date: Date? = nil) { let newRequest = BGProcessingTaskRequest(identifier: BGTaskIdentifier.smartwalking.rawValue) newRequest.requiresNetworkConnectivity = true newRequest.requiresExternalPower = false if let seconds = seconds { newRequest.earliestBeginDate = Date().addingTimeInterval(seconds) } else if let date = date { newRequest.earliestBeginDate = date } do { try BGTaskScheduler.shared.submit(newRequest) debugPrint("✅ [BGTasksManager] scheduled for Smart Walking Sync") } catch { FirebaseConnection.shared.recordException(error) debugPrint("❌ [BGTasksManager] error: \(error)") } } // Handle Smart Walking Sync Task func handleSmartWalkingSync(task: BGProcessingTask) { debugPrint("🔄 [BGTasksManager] sync \(task.identifier) sync started") scheduleSmartWalkingSync(in: SYNC_SMARTWALKING_TIME_INTERVAL) let queue = OperationQueue() let operation = HealthActivitiesOperation() operation.completionBlock = { Task { do { try await operation.sync() task.setTaskCompleted(success: !operation.isCancelled) debugPrint("✅ [BGTasksManager] sync \(task.identifier) completed successfully") } catch { FirebaseConnection.shared.recordException(error) task.setTaskCompleted(success: false) debugPrint("❌ [BGTasksManager] sync \(task.identifier) error: \(error)") } } } task.expirationHandler = { operation.cancel() } queue.addOperation(operation) } // MARK: - HealthKit Background Delivery internal func enableBackgroundDeliveryForAllTypes() async throws { for type in allTypes.filter({ type in type != HKQuantityType(.heartRate) }) { try await healthStore.enableBackgroundDelivery(for: type, frequency: .daily) } debugPrint("✅ [HealthKitManager] Enable Background Delivery") } internal func observeHealthKitQuery(predicate: NSPredicate?) async throws -> Set<HKSampleType> { let queryDescriptors: [HKQueryDescriptor] = allTypes .map { type in HKQueryDescriptor(sampleType: type, predicate: predicate) } return try await withCheckedThrowingContinuation { continuation in var hasResumed = false let query = HKObserverQuery(queryDescriptors: queryDescriptors) { query, updatedSampleTypes, completionHandler, error in if hasResumed { return } if let error = error { continuation.resume(throwing: error) } else { continuation.resume(returning: updatedSampleTypes ?? []) } hasResumed = true completionHandler() } healthStore.execute(query) } } internal func getHealthActivity(by date: Date, predicate: NSCompoundPredicate, sampleTypes: Set<HKSampleType>) async throws -> HealthActivityData { var data = HealthActivityData(steps: 0, calories: 0, distance: 0.0, distanceCycling: 0.0, totalDuration: 0, date: date, heartRate: nil) for sampleType in sampleTypes { guard let quantityType = sampleType as? HKQuantityType else { continue } switch quantityType { case HKQuantityType(.stepCount): let stepCount = try await getDescriptor( date: date, type: quantityType ).result(for: healthStore) .statistics(for: date)?.sumQuantity()?.doubleValue(for: HKUnit.count()) data.steps = stepCount ?? 0.0 // Calculate total duration using HKSampleQueryDescriptor let totalDurationDescriptor = HKSampleQueryDescriptor( predicates: [.quantitySample(type: quantityType, predicate: predicate)], sortDescriptors: [SortDescriptor(\.endDate, order: .reverse)] ) let stepSamples = try await totalDurationDescriptor.result(for: healthStore) data.totalDuration += stepSamples .reduce(0) { $0 + $1.endDate.timeIntervalSince($1.startDate) } / 60.0 default: debugPrint("Unknown quantity type") } } return data }
2
0
841
Aug ’24
Apple Health `export.zip` doesn't include several important data points.
Heya, I'm currently building out my own application for tracking my health information, and I'm hoping to collect my historical data from Apple Health. Sadly, it would appear that certain things I wish to export don't appear in the export.xml file. Some of the things that I would expect to find in the export.xml file, that do not currently appear, are as follows: More data about my medications, currently I can only export a list of my medications, its not possible to export data such as when what medication was taken. Logged emotions; there is currently no support for this (that I can find). Would appreciate some insight into this.
1
0
804
Aug ’24
HealthKit data - Is HKStatisticsCollectionQuery slow?
Hi, I am using HealthKit for the first time. I am using HKStatisticsCollectionQuery. I am running my code iOS 17 on a physical iPhone. It takes several seconds to query data, for example 1 day worth of heart rate at 1 minute resolution. I changed the resolution to 1 hour, expecting it to be faster, but it's pretty much the same… I have been following the official documentation and sample code. I also compiled in Release, but that didn't really help for HKStatisticsCollectionQuery. I quickly looked with Instruments, the app is spending a lot of time in decoding data with NSXPCDecoder. Is there a way to speed data retrieval? Or this is "expected" latency?
Replies
2
Boosts
0
Views
1.3k
Activity
Oct ’24
Workout Effort Scores
Is there anywhere that describes in detail how third party workout apps can use the new effort score functionality? I can't see much in the documentation or any of the WWDC videos. In particular it would be useful to know if an effort score is automatically calculated for workouts created with third party apps? It doesn't seem to happen but some people say it takes weeks / months before watchOS starts calculating it for third party apps. If it doesn't happen automatically then how can the app set it? I tried the new relateWorkoutEffortSample API but that didn't work for me (see https://developer.apple.com/forums/thread/763539). If I could get it working then how should I determine a default effort score based on the workout metrics? Is that something that the app should do? If so then it would be good to be consistent with watchOS so some idea of how that is calculating effort scores would be useful. Sorry for all the questions, especially if there is an article in the documentation or a video that I have missed.
Replies
4
Boosts
0
Views
2.3k
Activity
Oct ’24
Missing manual - Training Load, .estimatedWorkoutEffortScore, .workoutEffortScore - Where are the Apple RPE CR-10 scale docs?
Apple is using the RPE scale for workout effort scores. This stands for the Rate of Perceived Exertion. They're specifically using the CR-10 scale, at least from what I can tell by saving values to HealthKit. They only accept value between 0 and 10. Has anyone been able to find a scientific or academic paper on how they have chosen their different effort breakouts? Right from the Fitness app on iPhone and Activity app on Apple Watch: 1-3 Easy 4-6 Moderate 7-8 Hard 9-10 All Out There is zero documentation on these new types, which makes it difficult for workout recording apps to properly and appropriately save this new data type. Sure, we can use the Apple apps as a reference, but since there isn't a built-in Apple SwiftUI sheet to present this data, and no references to academia to point our users to, our solutions would just look the same. FB15315876 - Documentation / HealthKit: Publish documentation about .workoutEffortScore and .estimatedWorkoutEffortScore FB15316109 - Documentation / HealthKit: Add documentation to .estimatedWorkoutEffortScore and .workoutEffortScore that you can't save those samples via the save API and that they must be related and let that API save the sample FB15316251 - Documentation / HealthKit: Add documentation for acceptible values of .estimatedWorkoutEffortScore and .workoutEffortScore - don't rely on a runtime error! Apple missed making an enum for all third party developers this year.
Replies
0
Boosts
1
Views
744
Activity
Oct ’24
How to add "Estimated Time in Each Heart Rate Zone" info to my custom HKWorkout when viewed in Apple Fitness app?
Hello, I’m currently developing a fitness app for watchOS that lets a user to manually set a desired heart rate target zone (enter numbers representing the lower and upper boundaries) and start a workout (right now it’s only “Other” type). After that my app monitors user’s heart rate and alerts them when they’re out of zone. When user ends the workout, the info about this workout appears on “Fitness” iOS app, and user can see the workout data like Workout Time, Active and Total Calories, Avg. Heart Rate. Also user can see Heart Rate chart with info how their heart rate was changing during a workout (see the Figure 1). Now to the question. When user clicks “Show More” button above the Heart Rate chart, they can see the same Heart Rate chart and another one, with Post-Workout Heart Rate (see the Figure 2). But there is no “Estimated time in each heart rate zone” as one can see in the workout’s details that were recorded from Apple’s workout (watchOS “Workout” app, for a workout of “Other” type as well). Please see the Figure 3. The question is: is it possible to add “Estimated time in each heart rate zone” to workout recorded via my third-party app so it would look like on the Figure 3 in "Fitness" iOS app, and if it's possible, what steps should I undertake to implement this ? Thanks in advance! I posted the screenshots in the replies to the post, because otherwise I was not able to submit a post ("sensitive language" warning, I suspect it's because of the ids in the attached screenshot's urls)
Replies
2
Boosts
0
Views
1.3k
Activity
Oct ’24
How to read Apple iOS 16 Heart Rate Zones from HealthKit
Is there way to read the Apple Heart rate zones from HealthKit? I want to read the min/max bpm for each of the 1-5 zones. I went through the Apple HealthKit developer documentation but couldn't find it https://developer.apple.com/documentation/healthkit
Replies
3
Boosts
2
Views
2.3k
Activity
Oct ’24
internal healthkit error: "Unable to invalidate interval: no data source avallable"
we are seeing what appears to be an internal healthkit error appearing in our app.  not sure if it's connected, but we've mostly seen it reported on devices running ios 16.  even though our app's primary language is japanese, and in all reported occurrences the app was running in japanese, the error message itself appears in english.  searching the error string on the web yields surprisingly few results (including only two mentions on this forum that i could find, neither of which seemed relevant).  this would seem to suggest that it's coming from something deep inside healthkit, since the error message is not localized.  in all reported cases, the user had recently upgraded to a new iphone.  in most cases, the problem only occurs on the new device even though everything had been working correctly prior to the upgrade.  the error occurs when the app is unable to read step count data from healthkit. we have confirmed that the app has been granted access permissions to all health data via os settings.  we've also tried having the user toggling those settings off, then back on, rebooting the device, deleting and reinstalling the app, etc., to no avail. the error message is "Unable to invalidate interval: no data source avallable." we'd appreciate it if anyone can shed more light on this issue. thanks!
Replies
4
Boosts
3
Views
1.9k
Activity
Oct ’24
HealthKit permission sheet appears every time for some users - bug?
The HealthKit permission sheet is showing up every time the app opens for a few users of my app. It doesn't matter what action they take in the sheet. I have had them try toggling the permissions from the HealthKit system settings but that did not happen to fix the problem. Has anyone experienced this problem or know a fix? Its affecting a few users of my app. I haven't been able to find what in my code could be doing this, I suspect its a bug on HealthKit's side for specific users. I can't find anyone reporting this problem elsewhere so I have to assume its my fault, but the docs clearly state that the permission sheet will only be presented once.
Replies
8
Boosts
9
Views
2.2k
Activity
Oct ’24
visionOS App Not Receiving Latest Heart Rate Data from HealthKit
Hello everyone, I'm developing an app for visionOS that utilizes HealthKit to query heart rate data. However, I'm encountering an issue where the app doesn't retrieve the latest heart rate values. Specifically, it fails to get live heart rate data even after the data has been saved to the Health app. The readings my app displays are outdated and do not match the current values shown in the Health app. Here's what I've tried so far: Fetching Heart Rate Samples: Used HKSampleQuery and HKAnchoredObjectQuery to fetch the most recent heart rate samples. Despite this, the data retrieved is still not up-to-date. Checking Permissions: Ensured that all necessary HealthKit permissions are granted. The app has authorization to read heart rate data and write workout data. My questions are: Is there a known issue or limitation with HealthKit on visionOS that prevents apps from accessing the latest heart rate data? Are there additional steps or configurations required to access live heart rate data in visionOS apps? Has anyone successfully implemented live heart rate monitoring on visionOS, and if so, could you share how you achieved it?
Replies
0
Boosts
0
Views
534
Activity
Sep ’24
HealthKit bugs related to new workout effort score - heart rate samples take forever to fetch, Health app displays invalid data
I am encountering issues on my device running iOS 18 that fetching heart rate samples associated to a given workout is very slow. Like 10+ seconds slow. This is unacceptable and unexpected. In producing a video to attach to a feedback, I also observed that Apple Health app displays incorrect information if a workout effort score is associated to a workout. In this image, you can see the Health app bug: Total Resting Energy != Estimated Workout Effort Score Here is the same workout after I delete the workout effort score using the Apple Health app: Can anyone else see if attempting to view 'heart rate' data within the workout summary in Apple Health is unbearably slow if that workout also has an effort score associated? My steps: Record workout (Apple Activity app on watchOS) Associate effort score View the workout on Apple Health (iOS) Attempt to view it's heart rate samples Observe very slow loading times Observe the incorrect cell label and value and disappearance of resting energy cell data Remove/disassociate the effort score from the workout by tapping the workout effort row, and swipe to delete the value. Navigate back, navigate back, and then go into the workout detail again At this time the UI fixes itself, but the loading of heart rate data is still super slow FB15269657 - HealthKit: Sample query to fetch heart rate samples associated to a workout is taking over 10 seconds - computing 'time in heart rate zone' FB15278790 - Health: Workout summary 'Total Resting Energy' label has value of 'Estimated Workout Effort Score' for a value, pushed view shows empty
Replies
0
Boosts
0
Views
772
Activity
Sep ’24
Wake-up detection with HealthKit
Hello HealthKit Experts & Enthusiasts! I am building an app called one sec which forces people to take a deep breath before they can use social media apps (it’s using Shortcuts Automations for that). One important feature of one sec is the Good Morning Countdown: For a specified time after waking up (e.g. 30mins) selected apps are blocked completely. This helps to start the day screen-free. They way it works is, the user grants access to read HKCategoryTypeIdentifier.sleepAnalysis data. I have implemented a HKObserverQuery and enableBackgroundDelivery in order to be informed whenever new HKCategoryTypeIdentifier.sleepAnalysis becomes available. I noticed that when I have my device connected to Xcode, this works as expected. However, when I quit the app and launch it from my Home Screen, my observer query is not informed about new sleep data (except when my app is running in foreground). Any ideas? Furthermore, I have noticed that sometimes sleep data is provided delayed to HealthKit, many minutes (sometimes even longer) after waking up, no sleep samples are to be found in the Health app. Of course, for my app it is crucial to get accurate + timely so apps can be blocked accordingly. Is this an issue that the Apple Watch first needs to send the samples to the phone? Thanks a lot for your help!
Replies
1
Boosts
1
Views
953
Activity
Sep ’24
Overlapping Segments and Duplicate Start Times in Workout Data
Hello, We're encountering overlapping segments and discrepancies when analyzing running/workout data for a 5-mile run. The expected splits for the run are: 8:39 9:06 8:30 8:39 8:43 0:08 However, the raw data includes segments where start times begin before the previous segment ends, and there are duplicate start times. Below is a sample of the raw data: "startDate": "2024-09-09T19:32:00.308-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T19:37:56.135-0400" }, { "startDate": "2024-09-09T19:32:00.308-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T19:41:08.476-0400" },``` // Here's an example of where the second segment start time falls in side the first segments startDate and endDate "startDate": "2024-09-09T19:54:22.658-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T19:59:41.215-0400" }, { "startDate": "2024-09-09T19:58:44.624-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T20:07:23.216-0400"
Replies
8
Boosts
0
Views
1k
Activity
Sep ’24
HKLiveWorkoutBuilder only reporting heart rate - No other measurements
I'm using Healthkit with the following H/W specs: Apple Watch, series 8, OS: 10.6.1 (21U580) iPhone 11 Pro, OS: 17.6.1 Mac Studio M1 Xcode ver: 16.0 (16A242d) I am trying to get Apple Watch to report heart rate, HRV, respiratory rate, and body temperature using Healthkit's HKLiveWorkoutBuilder implementing HKLiveWorkoutBuilderDelegate's workoutBuilder method. However, the only reported value that is found from the workoutBuilder method's collectedTypes (a Set of HKSampleType objects) is HKQuantityTypeIdentifierHeartRate. Nothing for HRV, respiratory rate, or body temperature. All entitlements are set up, the plist filled in, and capabilities in place. Not sure why only the heart rate is reported from the watch but nothing else. I've scoured StackOverflow, Apple developer forums, even ChatGPT but none of the solutions work. Any help most appreciate! The model code is: import Foundation import HealthKit class WatchModel: NSObject, HKLiveWorkoutBuilderDelegate, HKWorkoutSessionDelegate { private let healthStore = HKHealthStore() private var workoutSession: HKWorkoutSession! private var workoutBuilder: HKLiveWorkoutBuilder! override init() { super.init() requestAuthorization() startWorkoutSession() } private func requestAuthorization() { let heartRateType = HKQuantityType.quantityType(forIdentifier: .heartRate)! let respiratoryRateType = HKQuantityType.quantityType(forIdentifier: .respiratoryRate)! let HRVRateType = HKQuantityType.quantityType(forIdentifier: .heartRateVariabilitySDNN)! let temperatureRateType = HKQuantityType.quantityType(forIdentifier: .bodyTemperature)! let healthDataTypes: Set = [heartRateType, respiratoryRateType, HRVRateType, temperatureRateType] healthStore.requestAuthorization(toShare: healthDataTypes, read: healthDataTypes) { (success, error) in if !success { print("Authorization failed") } } } func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) { } func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: any Error) { } func workoutBuilderDidCollectEvent(_ workoutBuilder: HKLiveWorkoutBuilder) { } func startWorkoutSession() { let configuration = HKWorkoutConfiguration() configuration.activityType = .other configuration.locationType = .indoor do { workoutSession = try HKWorkoutSession(healthStore: healthStore, configuration: configuration) workoutBuilder = workoutSession.associatedWorkoutBuilder() workoutBuilder.delegate = self workoutBuilder.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: configuration) let dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: configuration) let respiratoryRate = HKQuantityType(.respiratoryRate) dataSource.enableCollection(for: respiratoryRate, predicate: nil) let bodyTemp = HKQuantityType(.bodyTemperature) dataSource.enableCollection(for: bodyTemp, predicate: nil) let hrv = HKQuantityType(.heartRateVariabilitySDNN) dataSource.enableCollection(for: hrv, predicate: nil) workoutSession.delegate = self workoutSession.startActivity(with: Date()) workoutBuilder.beginCollection(withStart: Date(), completion: { (success, error) in if let error = error { print("Error starting collection: \(error.localizedDescription)") } }) } catch { print("Failed to start workout session: \(error.localizedDescription)") } } func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>) { print("collected types: \(collectedTypes)") for type in collectedTypes { if let quantityType = type as? HKQuantityType { if quantityType == HKQuantityType.quantityType(forIdentifier: .heartRate) { if let heartRateQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let heartRateUnit = HKUnit(from: "count/min") let heartRateValue = heartRateQuantity.doubleValue(for: heartRateUnit) print("heart rate: \(heartRateValue)") } } if quantityType == HKQuantityType.quantityType(forIdentifier: .heartRateVariabilitySDNN) { if let hrvQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let hrvUnit = HKUnit.secondUnit(with: .milli) let hrvValue = hrvQuantity.doubleValue(for: hrvUnit) print("HRV: \(hrvValue)") } } if quantityType == HKQuantityType.quantityType(forIdentifier: .bodyTemperature) { if let bodyTempQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let tempUnit = HKUnit.degreeCelsius() let tempValue = bodyTempQuantity.doubleValue(for: tempUnit) print("body temp: \(tempValue)") } } if quantityType == HKQuantityType.quantityType(forIdentifier: .respiratoryRate) { if let respRateQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let respRateUnit = HKUnit(from: "count/min") let respRateValue = respRateQuantity.doubleValue(for: respRateUnit) print("breathing: \(respRateValue)") } } } } } }
Replies
6
Boosts
0
Views
1.2k
Activity
Sep ’24
recoverActiveWorkoutSession() inaccurate for paused sessions
When a workout session is being recovered, if it is paused, the elapsed time will be incorrect. It will seem like that workout never was paused. The recovery works fine if the workout was never paused. Steps to reproduce: Implement recoverActiveWorkoutSession Start workout Pause session and print the elapsed time Stop simulator / cause crash When recoverActiveWorkoutSession is called the elapsed time will not equal the elapsed time when the session was paused. Here is my implementation. I haven't seen any examples online. guard let recovered = try? await healthStore.recoverActiveWorkoutSession() else {return} self.session = recovered self.builder = recovered.associatedWorkoutBuilder() self.session?.delegate = self self.builder?.delegate = self self.builder?.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: recovered.workoutConfiguration) self.sessionState = recovered.state
Replies
1
Boosts
0
Views
919
Activity
Sep ’24
What's the correct way to check for unavailable API?
I ran into a problem recently with my production app and an update for iOS 18. In this example I was using a new API added to the RC candidate of iOS 18.0, using this API as an example, I couldn't find a satisfactory way to avoid crashing on iOS 18.1 where the API was not available. I had plenty of users running the iOS 18.1 Beta and ultimately it's my fault if a version of my app did work, and then didn't after an update.... This code causes a crash on iOS 18.1 beta as the .appleSleepingBreathingDisturbances API doesn't seem to have made it's way into the beta: if #available(iOS 18.0, *), #available(watchOS 11, *) { healthKitTypesToRead.insert(HKQuantityType.quantityType(forIdentifier: .appleSleepingBreathingDisturbances)!) } I tried this but it still crashed on 18.1: if #available(iOS 18.0, *), #available(watchOS 11, *) { if let newQuantity = HKQuantityType.quantityType(forIdentifier: .appleSleepingBreathingDisturbances) { healthKitTypesToRead.insert(newQuantity) } } In the end the only way I could resolve this was the following: if #available(iOS 18.1, *){ // Do nothing } else if #available(iOS 18.0, *), #available(watchOS 11, *) { if let newQuantity = HKQuantityType.quantityType(forIdentifier: .appleSleepingBreathingDisturbances) { healthKitTypesToRead.insert(newQuantity) } } This seems like a poor solution and I'll have to ensure I release a new version of the app once iOS 18.1 has the available API added to enable support for the feature. How could I have checked availability for this API correctly without causing the app to crash? I'm asking this question more as a Swift language feature rather than issue with the specific API as I'm sure that will get resolved soon anyway. Thanks
Replies
4
Boosts
1
Views
1.5k
Activity
Sep ’24
Regular step count fetch and upload to API
Hello all, I am quite new to iOS and Swift, and before venturing further, I feel it's better to ask for advice. I have build a Type I diabetes simulator running as a NodeJS application on a server. The clients authenticate via a browser using Fitbit/Google oauth2, set up a virtual patient, then take care of the patient 24/7. The app imports the users steps and heartrate, as these influence the blood sugar variations. (https://cgmsim.com) I designed a companion app with Expo, adding high/log blood glucose alerts with push notifications. If the user doesn't have a Fitbit tracker or doesn't use Google Fit, I'd like to send their HealthKit step counts to the backend. (Using sensor data directly in Android). It works using Expo's Background Fetch and TaskManager, but the uploads from the iOS device are very irregular. I set up silent push notifications from the backend to wake up the app in the background and trigger the step count upload. It works, but it is not reliable enough. I now wrote my first local native module for iOS, where a HKObserverQuery listening for new step events, making the upload and sending the count to the JS for rendering. I used enableBackgroundDelivery and BackgroundTask for uploading the results. All the entitlements and Info.plist entries should be ok. Still my app works well only in the foreground, and not upload at all happens when in the background. As we all do, I asked Claude, and it assured me th app should work. I have doubts though, as I noticed how strict iOS is about executing background tasks. So... should I even expect this to work ?
Replies
1
Boosts
0
Views
1.2k
Activity
Sep ’24
Workouts, activity rings, samples and more not syncing across devices running iOS 18 RC and watchOS 11 RC
I noticed last night that workouts I have been recording on my main carry device running 17.6.x have not been syncing to my beta devices running iOS 18 RC, iPadOS 18 RC and watchOS 11 RC. All devices are using the same Apple Account and I have iCloud enabled for Health data. The iPad running the RC has the syncing enabled in Profile. Is anyone else experiencing health data not propagating to the 18.x devices? Some of data exists on all devices but not all. For good measure I left the device unlocked on the health app last night for a long period of time to let it do its thing. This morning the data still hadn't propagated. I disabled and reenabled the synchronization on my iPad having chosen to delete all samples when disabling it. Hopefully all of my data dating back to the first Apple Watch in 2014 restores. FWIW my data set according to iCloud settings my health dataset is just shy of 650 MB. FB15102443 - Health / HealthKit: Workouts, activity rings, sample data, and more not syncing via iCloud to 18 RC device
Replies
0
Boosts
0
Views
673
Activity
Sep ’24
Health Export not complete
Good evening, when I use the automatic export feature from my iPhone, it successfully exports data. When reading the Export.xml file it is dispayed completely, with about 3 mio lines. When I check the file I see, that a lot of data is missing. E.g. the iPhone dispays the heart rates for several exercises (from last year), which don't have any correspondence in the export.xml file. Current exercises have. I am a developer myself and parsed all files without any error. My iPhone has enough free space (200GB or so) and iCloud has more than a TB free. Internet is connected via 1GBit line, WLAN with 800MBit and everything runs smooth. I would like to get a COMPLETE export of all the health data, without having to write a program on my own to accomplish this. Thank you. /C
Replies
0
Boosts
0
Views
526
Activity
Aug ’24
I have rejection issues: Healthkit
Like my post title? I'm having issues getting my app accepted by the app store. I keep getting the message: Guideline 2.5.1 - Performance - Software Requirements Your app's binary includes references to HealthKit components, but the app does not appear to include any primary features that require health or fitness data. I don't have healthkit implemented anywhere in my app. I sifted through my app and: Healthkit is not implemented in my infoplist There are no HK imports My app doesn't reveal any references to "Health Kit" when I do a project wide search. The only thing I can think of is that there's an issue with my use of firebase. I'm wondering if I somehow inserted healthkit functionality in to firebase accidentally. Has anyone else had this problem before? If so, how did you solve it? Also. How do you rid of healthkit functionality or references to healthkit within firebase?
Replies
4
Boosts
0
Views
870
Activity
Aug ’24
BGTaskScheduler with
I’m trying to use BGProcessingTaskRequest to fetch step data in the background and send it. However, when I combine BGProcessingTaskRequest, HKObserverQuery, and healthStore.enableBackgroundDelivery, the results sometimes return zero. When I don’t schedule the BGProcessingTaskRequest, the data retrieved using HKObserverQuery and HKSampleQueryDescriptor is correct. // Register Smart Walking Sync Task func registerSmartWalkingSync() { #if !targetEnvironment(simulator) BGTaskScheduler.shared.register(forTaskWithIdentifier: BGTaskIdentifier.smartwalking.rawValue, using: nil) { task in guard let task = task as? BGProcessingTask else { return } self.handleSmartWalkingSync(task: task) } #endif } func scheduleSmartWalkingSync(in seconds: TimeInterval? = nil, at date: Date? = nil) { let newRequest = BGProcessingTaskRequest(identifier: BGTaskIdentifier.smartwalking.rawValue) newRequest.requiresNetworkConnectivity = true newRequest.requiresExternalPower = false if let seconds = seconds { newRequest.earliestBeginDate = Date().addingTimeInterval(seconds) } else if let date = date { newRequest.earliestBeginDate = date } do { try BGTaskScheduler.shared.submit(newRequest) debugPrint("✅ [BGTasksManager] scheduled for Smart Walking Sync") } catch { FirebaseConnection.shared.recordException(error) debugPrint("❌ [BGTasksManager] error: \(error)") } } // Handle Smart Walking Sync Task func handleSmartWalkingSync(task: BGProcessingTask) { debugPrint("🔄 [BGTasksManager] sync \(task.identifier) sync started") scheduleSmartWalkingSync(in: SYNC_SMARTWALKING_TIME_INTERVAL) let queue = OperationQueue() let operation = HealthActivitiesOperation() operation.completionBlock = { Task { do { try await operation.sync() task.setTaskCompleted(success: !operation.isCancelled) debugPrint("✅ [BGTasksManager] sync \(task.identifier) completed successfully") } catch { FirebaseConnection.shared.recordException(error) task.setTaskCompleted(success: false) debugPrint("❌ [BGTasksManager] sync \(task.identifier) error: \(error)") } } } task.expirationHandler = { operation.cancel() } queue.addOperation(operation) } // MARK: - HealthKit Background Delivery internal func enableBackgroundDeliveryForAllTypes() async throws { for type in allTypes.filter({ type in type != HKQuantityType(.heartRate) }) { try await healthStore.enableBackgroundDelivery(for: type, frequency: .daily) } debugPrint("✅ [HealthKitManager] Enable Background Delivery") } internal func observeHealthKitQuery(predicate: NSPredicate?) async throws -> Set<HKSampleType> { let queryDescriptors: [HKQueryDescriptor] = allTypes .map { type in HKQueryDescriptor(sampleType: type, predicate: predicate) } return try await withCheckedThrowingContinuation { continuation in var hasResumed = false let query = HKObserverQuery(queryDescriptors: queryDescriptors) { query, updatedSampleTypes, completionHandler, error in if hasResumed { return } if let error = error { continuation.resume(throwing: error) } else { continuation.resume(returning: updatedSampleTypes ?? []) } hasResumed = true completionHandler() } healthStore.execute(query) } } internal func getHealthActivity(by date: Date, predicate: NSCompoundPredicate, sampleTypes: Set<HKSampleType>) async throws -> HealthActivityData { var data = HealthActivityData(steps: 0, calories: 0, distance: 0.0, distanceCycling: 0.0, totalDuration: 0, date: date, heartRate: nil) for sampleType in sampleTypes { guard let quantityType = sampleType as? HKQuantityType else { continue } switch quantityType { case HKQuantityType(.stepCount): let stepCount = try await getDescriptor( date: date, type: quantityType ).result(for: healthStore) .statistics(for: date)?.sumQuantity()?.doubleValue(for: HKUnit.count()) data.steps = stepCount ?? 0.0 // Calculate total duration using HKSampleQueryDescriptor let totalDurationDescriptor = HKSampleQueryDescriptor( predicates: [.quantitySample(type: quantityType, predicate: predicate)], sortDescriptors: [SortDescriptor(\.endDate, order: .reverse)] ) let stepSamples = try await totalDurationDescriptor.result(for: healthStore) data.totalDuration += stepSamples .reduce(0) { $0 + $1.endDate.timeIntervalSince($1.startDate) } / 60.0 default: debugPrint("Unknown quantity type") } } return data }
Replies
2
Boosts
0
Views
841
Activity
Aug ’24
Apple Health `export.zip` doesn't include several important data points.
Heya, I'm currently building out my own application for tracking my health information, and I'm hoping to collect my historical data from Apple Health. Sadly, it would appear that certain things I wish to export don't appear in the export.xml file. Some of the things that I would expect to find in the export.xml file, that do not currently appear, are as follows: More data about my medications, currently I can only export a list of my medications, its not possible to export data such as when what medication was taken. Logged emotions; there is currently no support for this (that I can find). Would appreciate some insight into this.
Replies
1
Boosts
0
Views
804
Activity
Aug ’24