HealthKit

RSS for tag

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

HealthKit Documentation

Posts under HealthKit tag

108 Posts
Sort by:
Post not yet marked as solved
1 Replies
486 Views
hello We are currently developing using Healthkit. Starting with xcode15, healthkit throws an error. The code causing the error is HKQuantityType(.stepCount). When I use this code An EXC_BAD_ACCESS (code=1, address=0x0) error occurs. The error is: AppDelegate It also appears when I call didFinishLaunchingWithOptions. Is the linker the problem? Or is the Swift version the problem? Or HealthKit? Cleaning and initializing DerivedData I also tried downgrading DriverKit 22.4, but the error still appears. Please tell me how to solve this problem. Test model information is as follows: -iPhone 14 Pro iOS 16.5.1
Posted
by
Post not yet marked as solved
0 Replies
339 Views
hello After updating to xcode 15.1 while using xcode 14.3, I keep getting EXC_BAD_ACCESS (code=1, address=0x0) in HealthKit's HKQuantityType(.stepCount). We also created and tested HKQuantityType(.stepCount) in the appDelegate class. But it comes out the same as above. I think there has been a change in library building and linking starting from xcode15. Please guide me what to do about this problem. The test model is iphone 14 pro It's 16.5.1.
Posted
by
Post not yet marked as solved
0 Replies
419 Views
Errors: ''Invalid info.plist key. The key 'NSHealthShareUsageDescription'' ''Invalid info.plist key. The key 'NSHealthUpdateUsageDescription'' The app works fine when I just run it on hardware without deployment, but as soon as I try to distribute it, this shows up. The keys above are both defined and described in my App and extensions lists, so what's wrong?
Posted
by
Post not yet marked as solved
0 Replies
335 Views
I have the same issues, when i use HKStatisticsCollectionQuery query user step count, there's a big difference in the number of steps I'm query before and after a minute's interval. 2023-12-17 15:45:41 steps=529 2023-12-17 15:46:52 steps=5817 2023-12-19 19:43:59 steps=2680 2023-12-19 19:44:31 steps=5554 What is causing this issue? I would like some assistance, please.
Posted
by
Post not yet marked as solved
0 Replies
394 Views
With the recent iPad OS 17 release, Apple added the Health app for the first time. Looking at it, it seems pretty similar to the phone version as the Health app only shows 'historical' health data. My question is this: We are developing an iPad based fitness app. Is there any way of getting real-time health data from the Apple Watch directly to an iPad app? (basically, we just need heart rate). Or, do we have create some sort of workflow through the Phone like Watch -> iPhone running our app -> our servers -> iPad running our app ..to get that real-time data? We really just want Watch -> iPad running our app. I'm afraid I already know the answer but just thought I'd check in case I'm missing something in iOS 17. Thanks!
Posted
by
Post not yet marked as solved
1 Replies
397 Views
Our app uses HKWorkoutSession after some actions, to keep app on high priority in background and to keep Apple Watch returns to our app when the watch is waked up. We don't collect or register any activity record. But for some reasons, some users reviewed our app saying that when they're using our app, the Workout app on Apple Watch seems to be affected, ex: Move and exercises is recorded as an abnormal/impossible value... . Is this possible? I don't see any document mention this side effect?
Posted
by
Post not yet marked as solved
0 Replies
371 Views
Hello, it is discussed here https://developer.apple.com/videos/play/wwdc2023/10016/ (12:16) regarding WorkoutComposition, but unfortunately, I cannot find this class or structure in the documentation. Has this concept been removed?
Posted
by
Post not yet marked as solved
1 Replies
401 Views
I have created a new project and I have added HomeKit capability but the two control box for Clinical Health Records and Background Delivery can not be switched on. are there any suggestion? thanks a lot valerio
Posted
by
Post not yet marked as solved
0 Replies
316 Views
After some years our app has been writing some data to HealthKit we decided to remove this functionality from the app. Permissions were removed from requestAuthorization(toShare:read:completion:) method. For new users everything works fine, but for users who were already asked for writing permission in Settings toggles for permissions are still on. Is it any way to update toggles list in Settings for actual state of permissions? Thanks in advance.
Posted
by
Post not yet marked as solved
2 Replies
383 Views
Hi, Our app has an HKObserverQuery and calls enableBackgroundDelivery(...) While running on an iPhone the background wakeup happens. While running on an iPad, it doesn't. The app can successfully query for data while in the foreground on an iPad. Is background delivery expected to work on iPad?
Posted
by
Post not yet marked as solved
0 Replies
337 Views
Even if you have granted read permission for specific health data items (such as walking, weight, etc.), calling the function below will return the permission as 'sharingDenied'. How can I obtain 'sharingAuthorized'? let stepType = HKObjectType.quantityType(forIdentifier: .stepCount)! let authorizationStatus = HKHealthStore().authorizationStatus(for: stepType) //authorizationStatus => sharingDenied
Posted
by
Post not yet marked as solved
0 Replies
381 Views
https://idmsa.apple.com/IDMSWebAuth/signin?path=%2F%2Fforums%2Fpost%2Fquestion%3Flogin%3Dtrue&language=US-EN&instanceId=EN&appIdKey=25138a77e3499638936f018102a53961c923f72b517d4a4d6aee9f09529baca9&rv=4 I've built and tested the code obtained from this site, but although the session starts, pausing or stopping it doesn't seem to work properly. Does anyone know what might be causing this issue? I'm using the latest versions of iOS and watchOS, and my Xcode is version 15.0.1. The main code is as follows, and the session does not start properly in startWorkout. import Foundation import os import HealthKit @MainActor class WorkoutManager: NSObject, ObservableObject { struct SessionSateChange { let newState: HKWorkoutSessionState let date: Date } @Published var sessionState: HKWorkoutSessionState = .notStarted @Published var heartRate: Double = 0 @Published var activeEnergy: Double = 0 @Published var speed: Double = 0 @Published var power: Double = 0 @Published var cadence: Double = 0 @Published var distance: Double = 0 @Published var water: Double = 0 @Published var elapsedTimeInterval: TimeInterval = 0 @Published var workout: HKWorkout? let typesToShare: Set = [HKQuantityType.workoutType(), HKQuantityType(.dietaryWater)] let typesToRead: Set = [ HKQuantityType(.heartRate), HKQuantityType(.activeEnergyBurned), HKQuantityType(.distanceWalkingRunning), HKQuantityType(.cyclingSpeed), HKQuantityType(.cyclingPower), HKQuantityType(.cyclingCadence), HKQuantityType(.distanceCycling), HKQuantityType(.dietaryWater), HKQuantityType.workoutType(), HKObjectType.activitySummaryType() ] let healthStore = HKHealthStore() var session: HKWorkoutSession? #if os(watchOS) var builder: HKLiveWorkoutBuilder? #else var contextDate: Date? #endif let asynStreamTuple = AsyncStream.makeStream(of: SessionSateChange.self, bufferingPolicy: .bufferingNewest(1)) static let shared = WorkoutManager() private override init() { super.init() Task { for await value in asynStreamTuple.stream { await consumeSessionStateChange(value) } } } /** Consume the session state change from the async stream to update sessionState and finish the workout. */ private func consumeSessionStateChange(_ change: SessionSateChange) async { sessionState = change.newState /** Wait for the session to transition states before ending the builder. */ #if os(watchOS) /** Send the elapsed time to the iOS side. */ let elapsedTimeInterval = session?.associatedWorkoutBuilder().elapsedTime(at: change.date) ?? 0 let elapsedTime = WorkoutElapsedTime(timeInterval: elapsedTimeInterval, date: change.date) if let elapsedTimeData = try? JSONEncoder().encode(elapsedTime) { await sendData(elapsedTimeData) } guard change.newState == .stopped, let builder else { return } let finishedWorkout: HKWorkout? do { try await builder.endCollection(at: change.date) finishedWorkout = try await builder.finishWorkout() session?.end() } catch { Logger.shared.log("Failed to end workout: \(error))") return } workout = finishedWorkout #endif } } // MARK: - Workout session management // extension WorkoutManager { func resetWorkout() { #if os(watchOS) builder = nil #endif workout = nil session = nil activeEnergy = 0 heartRate = 0 distance = 0 water = 0 power = 0 cadence = 0 speed = 0 sessionState = .notStarted } func sendData(_ data: Data) async { do { try await session?.sendToRemoteWorkoutSession(data: data) } catch { Logger.shared.log("Failed to send data: \(error)") } } } extension WorkoutManager: HKWorkoutSessionDelegate { nonisolated func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) { Logger.shared.log("Session state changed from \(fromState.rawValue) to \(toState.rawValue)") let sessionSateChange = SessionSateChange(newState: toState, date: date) asynStreamTuple.continuation.yield(sessionSateChange) } nonisolated func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) { Logger.shared.log("\(#function): \(error)") } nonisolated func workoutSession(_ workoutSession: HKWorkoutSession, didDisconnectFromRemoteDeviceWithError error: Error?) { Logger.shared.log("\(#function): \(error)") } nonisolated func workoutSession(_ workoutSession: HKWorkoutSession, didReceiveDataFromRemoteWorkoutSession data: [Data]) { Logger.shared.log("\(#function): \(data.debugDescription)") Task { @MainActor in do { for anElement in data { try handleReceivedData(anElement) } } catch { Logger.shared.log("Failed to handle received data: \(error))") } } } } private func startWorkout() { Task { do { let configuration = HKWorkoutConfiguration() configuration.activityType = .cycling configuration.locationType = .outdoor try await workoutManager.startWorkout(workoutConfiguration: configuration) } catch { Logger.shared.log("Failed to start workout \(error))") } } }
Posted
by
Post not yet marked as solved
0 Replies
357 Views
With iOS 17 creation of HKWorkout is deprecated via its init functions and the recommendation is to use HKWorkoutBuilder. If you try to init HKWorkout like you would pre iOS 17 you get this warning of deprecation: The problem is that I am creating this HKWorkout object inside unit tests in order to test a service that works with such objects. And HKWorkoutBuilder requires a HKHealthStore which itself requires to be authenticated to be able to create HKWorkoutActivity instances, like it would be when an app is running. But since the unit tests cannot accept the request on the HKHealthStore I am not sure if using HKWorkoutBuilder inside unit tests is possible. I've also tried to inherit HKHealthStore and override all of its methods, but still, store requires authorization. Any ideas on how to proceed with creating HKWorkout for unit test purposes?
Posted
by
Post not yet marked as solved
0 Replies
260 Views
Hello developers, I hope you're all doing well. I've encountered an issue that I'm struggling to resolve, and I'd greatly appreciate any insights or assistance you can offer. Issue Summary: In my watchOS app, I'm utilizing the HKWorkoutSessionDelegate protocol and the workoutSession(_:didFailWithError:) method. While everything works smoothly on watchOS 9.*, I'm facing a problematic inconsistency on watchOS 10.0 and higher. Steps to Reproduce: Create a new watchOS project with a deployment target of watchOS 10.0 or higher. Implement the HKWorkoutSessionDelegate protocol and the workoutSession(_:didFailWithError:) method. Attempt to start a workout session. Expected Behavior: I expect the workout session to commence without any issues, and the delegate method to gracefully handle any errors, without displaying an error message. Actual Behavior: Unfortunately, on watchOS 10.0 and higher, my attempts to initiate a workout session result in an error message: "Cannot start workout session while process is in the background." Version/Build: Affected watchOS versions: 10.0 and higher Non-affected watchOS versions: 9.* Reproducibility: I've confirmed that this issue is reproducible across different projects and on different simulators running watchOS 10.0 and higher. Additional Information: This inconsistency seems to be specific to watchOS versions 10.0 and higher and doesn't occur on watchOS 9.*. It's causing confusion and hampering my development process, and the error message isn't as informative as I'd like. Workaround: I've been unable to identify a workaround for this issue so far. If any of you have insights, solutions, or suggestions, I'd be grateful for your input. Please feel free to share your experiences and thoughts on this matter. Your help is greatly appreciated! Thank you for your time and assistance. Best regards, Leonid
Posted
by
Post marked as solved
2 Replies
355 Views
iPadOS 17 brings HealthKit to the iPad. So I've updated my HealthKit-using app to also run on iPadOS. I can debug it from Xcode on iPad simulators and my iPad, but when I upload a build to AppStoreConnect from Xcode and try to install it on my iPad from TestFlight, the install-button is missing and instead there is a label saying "incompatible hardware". The app has no other required device capabilities besides healthkit. It was also updated to at least require iOS/iPadOS 17. I can install it on my iPhone but not on the iPad. I also noticed that in this list https://developer.apple.com/support/required-device-capabilities/#ipad-devices no iPad model has the healthkit device capability. Why? Is there some way to find out why exactly TestFlight thinks the iPad is incompatible hardware? Thanks in advance to anyone who can enlighten me here.
Posted
by
Post not yet marked as solved
2 Replies
429 Views
In the wwdc2023-10023 session, we go over how the Apple Watch can be used as a primary workout session manager and the iPhone as the mirrored one. How is it possible to create a workout session on the iPhone and optionally mirror it to the Apple Watch to collect heart rate data? In iOS 17, I still cannot instantiate a HKWorkoutSession, I'm assuming it says it's available because we can have an instance of it as a mirrored copy from the Apple Watch. I find it odd that the iPhone cannot manage the primary session. I hope I'm missing something.
Posted
by
Post not yet marked as solved
0 Replies
375 Views
Hi, with iOS 17 creation of HKWorkout is deprecated via its init functions and the recommendation is to use HKWorkoutBuilder: The problem is that I am creating this HKWorkout object inside unit tests in order to test a service that works with such objects. And HKWorkoutBuilder requires a HKHealthStore which itself requires to be authenticated to be able to create HKWorkoutActivity instances, like it would be when an app is running. But since the unit tests cannot accept the request on the HKHealthStore I am not sure if using HKWorkoutBuilder inside unit tests is possible. Any ideas on how to proceed with creating HKWorkout for unit test purposes?
Posted
by
Post not yet marked as solved
0 Replies
391 Views
The app I distribute has a function that retrieves step count information from the "Healthcare" app and displays it on the app, but depending on the device, the step count may not be retrieved. When I checked the settings of the "Healthcare" app, I found that it was properly linked to the app, but for some reason I was unable to retrieve it. Is there any countermeasure in such a case? Is there anyone who has experienced a similar incident?*The same issue occurs even if the device is changed and the same Apple ID is used, so I think it is caused by the Apple ID.
Posted
by
Post not yet marked as solved
1 Replies
393 Views
Hi, I am having some trouble with uploading HealthKit data to AWS S3 in the background. As of now, when I click on the button to beginBackgroundUpdates the data is uploaded as expected. When I go off the app and add data to HealthKit nothing happens. When I go back to the app, the new data is uploaded. I am not sure why this is not happening in the background. More specifically, I am not sure if this is allowed, and if so what I am doing wrong. ContentView: import SwiftUI import HealthKit struct ContentView: View { @StateObject var healthKitManager = HealthKitManager() var body: some View { VStack { Button("Enable Background Step Delivery") { healthKitManager.beginBackgroundUpdates() } } .padding() .onAppear { healthKitManager.requestAuthorization { success in print("Configured HealthKit with Return: \(success)") } } } } #Preview { ContentView() } BackgroundDeliveryApp: import SwiftUI import HealthKit import Amplify import AWSS3StoragePlugin import AWSCognitoAuthPlugin @main struct HKBackgruondDeliveryApp: App { private func configureAmplify() { do { try Amplify.add(plugin: AWSCognitoAuthPlugin()) try Amplify.add(plugin: AWSS3StoragePlugin()) try Amplify.configure() print("Succesfully configured Amplify with S3 Storage") } catch { print("Could not configure Amplify") } } init() { configureAmplify() } var body: some Scene { WindowGroup { ContentView() } } } HealthKitManager import Foundation import HealthKit import Amplify struct TestStep: Encodable, Decodable { let count: Double let startDate: Date let endDate: Date let device: String } class HealthKitManager: ObservableObject { var healthStore: HKHealthStore? let stepType = HKObjectType.quantityType(forIdentifier: .stepCount) let heartRateType = HKQuantityType(.heartRate) let sleepType = HKObjectType.categoryType(forIdentifier: .sleepAnalysis) init() { if HKHealthStore.isHealthDataAvailable() { healthStore = HKHealthStore() } else { print("There is no health data available") healthStore = nil } } func encodeStepList(stepList: [TestStep]) -> Data{ let encoder = JSONEncoder() encoder.dateEncodingStrategy = .iso8601 do { return try encoder.encode(stepList) } catch { return Data() } } func uploadStepData(stepList: [TestStep]) async { let stepData = self.encodeStepList(stepList: stepList) let uploadTask = Amplify.Storage.uploadData( key: "ExampleKey", data: stepData ) Task { for await progress in await uploadTask.progress { print("Progress: \(progress)") } } do { let value = try await uploadTask.value print("Completed: \(value)") } catch { print("Could not upload step data") } } func requestAuthorization(completion: @escaping (Bool) -> Void) { guard let stepType = stepType, let sleepType = sleepType else { return completion(false) } guard let healthStore = self.healthStore else { return completion(false) } healthStore.requestAuthorization(toShare: [], read: [stepType, heartRateType, sleepType]) { success, error in if let error = error { print("Some error has occoured during authorization of healthKit") print(error) } return completion(success) } } func beginBackgroundUpdates() { guard let healthStore = healthStore, let stepType = stepType else { print("Cannot begin background updates because HealthStore is nil") return } healthStore.enableBackgroundDelivery(for: stepType, frequency: .immediate) { success, error in print("Background update of health data") if let error = error { print("Some error has occoured during the set up of the background observer query for steps") print(error) return } guard let query = self.createObserverQuery() else { print("Could not create a query for steps") return } healthStore.execute(query) } } func stepCountDeviceRecordsQuery(stepCountObjects: @escaping ([TestStep]) -> Void) { guard let stepType = stepType else { print("Nil step type") return } let stepCountUnit = HKUnit.count() let endDate = Date() let startDate = Calendar.current.date(byAdding: .day, value: -7, to: endDate) let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate) let sortDescriptors = [NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: true)] let stepCountQuery = HKSampleQuery(sampleType: stepType, predicate: predicate, limit: 10000, sortDescriptors: sortDescriptors) { query, results, error in if let error = error { print("Error in getStepCount") print(error) return } guard let results = results else { print("Empty results in getStepCount") return } var stepCounts: [TestStep] = [] for (_, record) in results.enumerated() { guard let record: HKQuantitySample = record as? HKQuantitySample else {return} let step = TestStep(count: record.quantity.doubleValue(for: stepCountUnit), startDate: record.startDate, endDate: record.endDate, device: record.device?.model ?? "") stepCounts.append(step) } print("\(stepCounts.count) records at \(Date())") print(stepCounts[stepCounts.count - 1]) stepCountObjects(stepCounts) } healthStore?.execute(stepCountQuery) } private func createObserverQuery() -> HKQuery? { guard let stepType = stepType else { return nil } let query = HKObserverQuery(sampleType: stepType, predicate: nil) { query, completionHandler, error in self.stepCountDeviceRecordsQuery { stepList in Task { await self.uploadStepData(stepList: stepList) } } completionHandler() } return query } }
Posted
by
Post not yet marked as solved
0 Replies
394 Views
Hi guys, I'm delveloping an app that use HealthData. I use this data: HKWorkoutType.workoutType(), HKObjectType.quantityType(forIdentifier: .heartRate)!, HKObjectType.quantityType(forIdentifier: .distanceSwimming)! I would like use Simulator to test app, but there aren't data. How can I import data? Now to test my app use only my iPhone, but in this way I don't test multiple device to test my app. Could you help me? Thank you. Filippo
Posted
by