Health & Fitness

RSS for tag

Explore the technical aspects of health and fitness features, including sensor data acquisition, health data processing, and integration with the HealthKit framework.

Health & Fitness Documentation

Posts under Health & Fitness subtopic

Post

Replies

Boosts

Views

Activity

Apple Watch Health App not launching
Hello. My Apple Watch Health App is not launching is stuck on the loading screen forever. In the debug console, This message is displayed. `SwiftUI/EnvironmentObject.swift:70: Fatal error: No ObservableObject of type WorkoutManager found. A View.environmentObject(_:) for WorkoutManager may be missing as an ancestor of this view. 2022-04-19 10:27:58.865727-0400 FitnessFriend WatchKit Extension[65428:475974] SwiftUI/EnvironmentObject.swift:70: Fatal error: No ObservableObject of type WorkoutManager found. A View.environmentObject(_:) for WorkoutManager may be missing as an ancestor of this view. (lldb)  If anybody could help, it would be greatly appreciated.
0
0
628
Apr ’22
Healthkit background delivery is not working
https://developer.apple.com/documentation/healthkit/hkhealthstore/1614175-enablebackgrounddelivery, as Apple official described the technical documentation, We can read the health data in HealthStore when the application is not started or in the Kill state, when the data in the health App is updated. But it doesn't work for me, I don't know why, I hope I can get the answer here, thank you very much! Here is my code: typealias AccessRequestCallback = (_ success: Bool, _ error: Error?) -> Void /// Helper for reading and writing to HealthKit. class HealthKitManager: NSObject {       static let shared = HealthKitManager()       private override init() {}       private let healthStore = HKHealthStore()   /// Requests access to all the data types the app wishes to read/write from HealthKit.   /// On success, data is queried immediately and observer queries are set up for background   /// delivery. This is safe to call repeatedly and should be called at least once per launch.   func requestAccessWithCompletion(completion: @escaping AccessRequestCallback) {     guard HKHealthStore.isHealthDataAvailable() else {       debugPrint("Can't request access to HealthKit when it's not supported on the device.")       return     }     let writeDataTypes = dataTypesToWrite()     let readDataTypes = dataTypesToRead()           healthStore.requestAuthorization(toShare: writeDataTypes, read: readDataTypes) { [weak self] success, error in       guard let strongSelf = self else { return }       if success {         debugPrint("Access to HealthKit data has been granted")         strongSelf.readHealthKitData()         strongSelf.setUpBackgroundDeliveryForDataTypes(types: readDataTypes)       } else {         debugPrint("Error requesting HealthKit authorization: \(error?.localizedDescription ?? "")")       }               DispatchQueue.main.async {         completion(success,error)       }     }   }     } // MARK: - Private private extension HealthKitManager {   /// Initiates an `HKAnchoredObjectQuery` for each type of data that the app reads and stores   /// the result as well as the new anchor.   func readHealthKitData() {     debugPrint("===============readHealthKitData================") //    HealthKitManager.shared.addLocalPush(title: "readHealthKitData")   }   /// Sets up the observer queries for background health data delivery.   ///   /// - parameter types: Set of `HKObjectType` to observe changes to.   private func setUpBackgroundDeliveryForDataTypes(types: Set<HKObjectType>) {     for type in types {       guard let sampleType = type as? HKSampleType else {         debugPrint("ERROR: \(type) is not an HKSampleType");         continue       }       var query: HKQuery!       query = HKObserverQuery(sampleType: sampleType, predicate: nil) { [weak self] query, completionHandler, error in         if error != nil {           debugPrint("observer query update handler called for type \(type), error: \(error?.localizedDescription ?? "")")           return         }         guard let strongSelf = self else { return }         strongSelf.queryForUpdates(type: type)         completionHandler()       }       healthStore.execute(query)       healthStore.enableBackgroundDelivery(for: type, frequency: .immediate) { success, error in         if error != nil {           debugPrint("enableBackgroundDeliveryForType handler called for \(type) - success: \(success), error: \(error?.localizedDescription ?? "")")           return         }         debugPrint("enableBackgroundDeliveryForType: \(type)")       }     }   }   /// Initiates HK queries for new data based on the given type   ///   /// - parameter type: `HKObjectType` which has new data avilable.   private func queryForUpdates(type: HKObjectType) { //    self.addLocalPush(title: "queryForUpdates")     switch type {     case HKObjectType.quantityType(forIdentifier: .bodyMass):       debugPrint("HKQuantityTypeIdentifier-BodyMass")     case HKObjectType.quantityType(forIdentifier: .height):       debugPrint("HKQuantityTypeIdentifier-Height")     case HKObjectType.quantityType(forIdentifier: .stepCount):       debugPrint("HKQuantityTypeIdentifier-StepCount")     case is HKWorkoutType:       debugPrint("HKWorkoutType")     default: debugPrint("Unhandled HKObjectType: \(type)")     }   }   /// Types of data that this app wishes to read from HealthKit.   ///   /// - returns: A set of HKObjectType.   private func dataTypesToRead() -> Set<HKObjectType> {     if #available(iOS 14.0, *) {       return Set(arrayLiteral:             HKObjectType.quantityType(forIdentifier: .bodyMass)!,             HKObjectType.quantityType(forIdentifier: .height)!,             HKObjectType.categoryType(forIdentifier: .handwashingEvent)!,             HKObjectType.quantityType(forIdentifier: .stepCount)!,             HKObjectType.quantityType(forIdentifier: .distanceCycling)!,             HKObjectType.workoutType())     } else {       return Set(arrayLiteral:             HKObjectType.quantityType(forIdentifier: .bodyMass)!,             HKObjectType.quantityType(forIdentifier: .height)!,             HKObjectType.quantityType(forIdentifier: .stepCount)!,             HKObjectType.quantityType(forIdentifier: .distanceCycling)!,             HKObjectType.workoutType())     }   }   /// Types of data that this app wishes to write to HealthKit.   ///   /// - returns: A set of HKSampleType.   private func dataTypesToWrite() -> Set<HKSampleType> {     if #available(iOS 14.0, *) {       return Set(arrayLiteral:             HKObjectType.quantityType(forIdentifier: .bodyMass)!,             HKObjectType.quantityType(forIdentifier: .height)!,             HKObjectType.categoryType(forIdentifier: .handwashingEvent)!,             HKObjectType.quantityType(forIdentifier: .stepCount)!,             HKObjectType.quantityType(forIdentifier: .distanceCycling)!,             HKObjectType.workoutType())     } else {       return Set(arrayLiteral:             HKObjectType.quantityType(forIdentifier: .bodyMass)!,             HKObjectType.quantityType(forIdentifier: .height)!,             HKObjectType.quantityType(forIdentifier: .stepCount)!,             HKObjectType.quantityType(forIdentifier: .distanceCycling)!,             HKObjectType.workoutType())     }   } } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {           window = UIWindow(frame: UIScreen.main.bounds)           let vc: ViewController = .init()     window?.rootViewController = vc     window?.makeKeyAndVisible()           healthKitManager.requestAccessWithCompletion() { success, error in       if success { print("HealthKit access granted") }       else { print("Error requesting access to HealthKit: \(error?.localizedDescription ?? "")") }     }           return true   }
1
0
1.6k
Apr ’22
ResearchKit and Swift Package Manager
Hello Apple & ResearchKit, As ResearchKit is open source I was wondering if you could shed some light on when (or if so) ResearchKit will support the Swift Package Manager (SPM) as an alternative to forking, Cocoapods and Carthage? Or would that be a community effort? And if it is a community effort which branch should be the starting point for such a change (main?)? And would you be willing to accept a major re-organisation of the code to better fit SPM? Regards, Jens
0
0
770
Apr ’22
SwiftUI how to get total Sleep hours from Healthkit
I have issue to request Authorization and get the total sleep hours from HealthKit func requestAuthorization(completion: @escaping (Bool) -> Void) {           let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!     let heartRate = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!     let spo2 = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.respiratoryRate)!     let sleepHours = HKObjectType.categoryType(forIdentifier: .sleepAnalysis)     let setType = Set(arrayLiteral: sleep_type_t) //error cannot find 'sleepType' in scope ****           guard let healthStore = self.healthStore else { return completion(false) }           healthStore.requestAuthorization(toShare: [], read: [stepType,heartRate,spo2,sleepHours]) { (success, error) in       completion(success)     }         }    func getSleepHours(completion: @escaping (_ sleepHours: String?) -> Void) {     let sampleType = HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis)!           // Get all samples from the last 24 hours     let endDate = Date()     let startDate = endDate.addingTimeInterval(-1.0 * 60.0 * 60.0 * 24.0)     let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: [])     let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)     // Sleep query     let sleepQuery = HKSampleQuery(sampleType: sampleType,predicate: predicate,limit: 0,sortDescriptors: [sortDescriptor]) { (query, results, error) -> Void in             if error != nil {return}             // Sum the sleep time             var minutesSleepAggr = 0.0             if let result = results {               for item in result {                 if let sample = item as? HKCategorySample {                   if sample.value == HKCategoryValueSleepAnalysis.asleep.rawValue && sample.startDate >= startDate {                       let sleepTime = sample.endDate.timeIntervalSince(sample.startDate)                       let minutesInAnHour = 60.0                       let minutesBetweenDates = sleepTime / minutesInAnHour                       minutesSleepAggr += minutesBetweenDates                   }                 }               }               let sleepHours = Double(String(format: "%.1f", minutesSleepAggr / 60))!               let sleepHours2 = "(sleepHours)"               completion(sleepHours2)               print("*** SLEEP HOURS: (String(describing: sleepHours))")             }       }               healthStore?.execute(sleepQuery)   }
0
0
721
May ’22
How to mimic the way apple implements medals in their fitness app?
Hi all, I am currently making a fitness app and want to replicate the way Apple incorporate medals in their Fitness app. They have a page called awards and it looks like a collection view of different medals that the user can unlock. Once unlocking a medal the user can tap on the medal and it opens to a full screen intractable scene where the user can rotate the medal etc. I have had a play around with SceneKit and managed to get a medal loaded into a scene and display it in the app. However my functionality does not look as smooth or as polished as Apples. Does anyone have any idea on how they have managed to present all of the different Scene-kit scenes in a collection-view for example? Or how they have achieved the smooth transition between tapping on the medal in the collection-view and the scene. I guess this is created using SwiftUI. Can this be replicated in Storyboards? Thanks!
4
0
3.2k
Feb ’23
Storing Customer's Health App Data "Steps" for future rewarding
we are planning to develop a new module on our rewarding system to reward our customers on their physical activities "number of steps" received from the Apple Health and Fitness API. the customers will have to consent the access to their health app to allow the integration ofcourse. the idea is to allow the customer to participate in a weekly competition, where we'll be counting the number of steps of each participants and accordingly rewards the top 3 participants. my question here, will apple allow us to store/count the customers' number of steps after getting the proper consent. if yes, than what might be the further limitations/restrictions on processing such data?
0
0
547
Jun ’22
HealthKit - Request share and read permission of same type on separate calls
Hi. In an app, I'm calling requestAuthorization(toShare: Set([HKSampleType.workoutType()]), read: nil) if a user decides that he wants to send workouts to HealthKit and I have a separate call to requestAuthorization if the user also wants to read workouts from HealthKit -> requestAuthorization(toShare: nil, read: Set([HKSampleType.workoutType()])). The problem is that if I do this, when I do a second call for the same type but with a different permission, HealthKit is going to delete my previous permission for that type. Can't I segregate the share and read permissions of a same type in different calls to requestAuthorization? If a type can have a share and read permissions, I always need to put that type in both toShare and read parameters on every call of requestAuthorization?
0
0
419
Jun ’22
detect when hand wash event is finished
Hello :) I'm trying to make Apple Watch app that can detect hand wash is finished. I followed workout app that apple provided, and succeed in getting hand wash count information . but how can I detect hand wash event when app is not foreground or executed. my full code is as below /* See LICENSE folder for this sample’s licensing information. Abstract: The start view. */ import SwiftUI import HealthKit var healthStore: HKHealthStore!     struct StartView: View {          @State var count: Int = 0     //     //  ContentView.swift     //  handwash     //     //  Created by pedro jung on 2022/06/09.     //                  var body: some View {                 Button(action: {                     checkHealthKit()                 }, label: {                     Text("Button\(self.count)")                 })             }             func checkHealthKit() {                 print(count)                 healthStore = HKHealthStore()                 let healthTypes = Set([                     HKCategoryType.categoryType(forIdentifier: .handwashingEvent)!                 ])                 healthStore.requestAuthorization(toShare: nil, read: healthTypes)                     { (success, error) in                         fetchHandWashing()                     }             }                          func fetchHandWashing() {                 let now = Date()                 let calendar = Calendar.current                 let yesterday = calendar.date(byAdding: .day, value: -1, to: calendar.startOfDay(for: now))                 let predicate = HKQuery.predicateForSamples(withStart: yesterday, end: now, options: [])                 let sortDescriptor = [NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: true)]                 let washingEvent = HKCategoryType.categoryType(forIdentifier: .handwashingEvent)!                 let query = HKSampleQuery(sampleType: washingEvent,                                                 predicate: predicate,                                                 limit: HKObjectQueryNoLimit,                                                 sortDescriptors: sortDescriptor) {                     (query, results, error) in                     guard error == nil else { print("error"); return }                     let format = DateFormatter()                     format.dateFormat = "yyyy-MM-dd HH:mm:ss"                     format.timeZone   = TimeZone(identifier: "Asia/Tokyo")                     print("\(format.string(from: yesterday!)) - \(format.string(from: now)) r \(results)esult 🥳:")                     if let tmpResults = results as? [HKCategorySample] {                         print(tmpResults.count)                                                  self.count=tmpResults.count                         tmpResults.forEach { (sample) in                             print(sample)                         }                     }                 }                 healthStore.execute(query)                 healthStore.enableBackgroundDelivery(                       for: washingEvent,                       frequency: .immediate,                       withCompletion: { succeeded, error in                         guard error != nil && succeeded else {                             self.count = self.count+1                             //send information!                                                                              return                         }                       // Background delivery is enabled                     }                 )                 let query2 = HKObserverQuery(                   sampleType: washingEvent,                   predicate: nil,                   updateHandler: { query, completionHandler, error in                     defer {                       completionHandler()                     }                     guard error != nil else {                       return                     }                     // TODO                                      })                 healthStore.execute(query2)              }      }
0
0
877
Jun ’22
Medications in HealthKit?
Exciting to see the new Medication tracking features coming to Health. As a medical app we're wondering if read/write access to these is coming to HealthKit? We're currently building prescription management into our app so it would be great to be able to let users also add these to Health to handle their adherence tracking.
4
9
3.3k
Jun ’23
HKObserverQuery updateHandler is getting fired twice in a row
Hi, I'm trying to implement HealthKit Background delivery for my app and I'm getting a strange behavior where the HKObserverQuery updateHandler is getting fired twice. I'm running Xcode 13.4 & iOS 15.5. 2022-06-10 10:05:58.725006+0200 Cori[79737:8949689] [HealthKit] Run Background Delivery Handler 2022-06-10 10:05:58.726283+0200 Cori[79737:8949689] [HealthKit] Run Background Delivery Handler 2022-06-10 10:05:58.736475+0200 Cori[79737:8949700] [HealthKit] New data: [200 mg/dL 4680E3F5-034A-4AED-843C-9066532AD459 "Salud" (15.5), "iPhone14,2" (15.5)metadata: { 2022-06-10 10:05:58.736632+0200 Cori[79737:8949700] [HealthKit] 1 new HKQuantityTypeIdentifierBloodGlucose samples 2022-06-10 10:05:58.736926+0200 Cori[79737:8949689] [persistence] HealthKit: Start import to Core Data 2022-06-10 10:05:58.737116+0200 Cori[79737:8949700] [HealthKit] New data: [200 mg/dL 4680E3F5-034A-4AED-843C-9066532AD459 "Salud" (15.5), "iPhone14,2" (15.5)metadata: { 2022-06-10 10:05:58.737985+0200 Cori[79737:8949689] [persistence] HealthKit: 1 samples of type HKQuantityTypeIdentifierBloodGlucose not from this app! 2022-06-10 10:05:58.753583+0200 Cori[79737:8949689] [persistence] HealthKit: Start batch insert request. 2022-06-10 10:05:58.753630+0200 Cori[79737:8949700] [HealthKit] 1 new HKQuantityTypeIdentifierBloodGlucose samples 2022-06-10 10:05:58.753873+0200 Cori[79737:8949689] [persistence] HealthKit: Start import to Core Data 2022-06-10 10:05:58.754019+0200 Cori[79737:8949689] [persistence] HealthKit: 1 samples of type HKQuantityTypeIdentifierBloodGlucose not from this app! 2022-06-10 10:05:58.754076+0200 Cori[79737:8949689] [persistence] HealthKit: Start batch insert request. 2022-06-10 10:05:58.759208+0200 Cori[79737:8949701] [persistence] HealthKit: Successfully imported data. 2022-06-10 10:05:58.759669+0200 Cori[79737:8949701] [persistence] HealthKit: Successfully imported data. This is my code: App Delegate extension AppDelegate {     public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {         if settings.syncHealthKit { HealthKit.shared.setUpBackgroundDelivery()         }         return true     } HealthKit Class class HealthKit: ObservableObject {     private let logger = Logger(subsystem: "com.ChubbyApps.Diabetes", category: "HealthKit")     private var dataController: DataController = .shared     private var ajustes: AjustesModel = .shared     public let isAvailable = HKHealthStore.isHealthDataAvailable()     private lazy var isAuthorized = false     // MARK: - Properties     private var anchor: HKQueryAnchor? {         get {             guard let data = NSUbiquitousKeyValueStore.default.object(forKey: Keys.HKAnchor) as? Data else {                 return nil             }             do {                 return try NSKeyedUnarchiver.unarchivedObject(ofClass: HKQueryAnchor.self, from: data)             } catch {                 logger.error("Unable to unarchive \(data): \(error.localizedDescription)")                 return nil             }         }         set(newAnchor) {             guard let newAnchor = newAnchor else {                 return             }             do {                 let data = try NSKeyedArchiver.archivedData(withRootObject: newAnchor, requiringSecureCoding: true)                 NSUbiquitousKeyValueStore.default.set(data, forKey: Keys.HKAnchor)             } catch {                 logger.error("Unable to archive \(newAnchor): \(error.localizedDescription)")             }         }     }     // MARK: - Initializers     static let shared = HealthKit()     // MARK: - Public Methods     public func requestAuthorization() async -> Bool {         guard isAvailable else { return false }         do {             try await HKStore.requestAuthorization(toShare: types, read: types)             self.isAuthorized = true             return true         } catch let error {             self.logger.error("An error occurred while requesting HealthKit Authorization: \(error.localizedDescription)")             return false         }     }     // MARK: - Background     func setUpBackgroundDelivery() {         let query: HKObserverQuery = HKObserverQuery(sampleType: glucose, predicate: nil, updateHandler: self.backgroundDeliveryHandler)         HKStore.execute(query)         HKStore.enableBackgroundDelivery(for: glucose, frequency: .immediate) { success, error in             if success {                 self.logger.debug("Enabled background delivery of stepcount changes")             } else {                 if let theError = error {                     self.logger.debug("Failed to enable background delivery of stepcount changes. Error: \(theError.localizedDescription)")                 }             }         }     }     func backgroundDeliveryHandler(query: HKObserverQuery!, completionHandler: HKObserverQueryCompletionHandler!, error: Error!) {         self.logger.debug("Run Background Delivery Handler")         self.anchoredQueryFor(types)          completionHandler()     }     private func anchoredQueryFor(_ tipos: Set<HKSampleType>) {         var queryDescriptors = [HKQueryDescriptor]()         for type in tipos {             queryDescriptors.append(HKQueryDescriptor(sampleType: type, predicate: nil))         }         let anchoredQuery = HKAnchoredObjectQuery(             queryDescriptors: queryDescriptors,             anchor: anchor,             limit: HKObjectQueryNoLimit) { _, newSamples, _, newAnchor, error in                 if let error = error {                     self.logger.error("HKAnchoredObjectQuery error: \(error.localizedDescription)")                     return                 }                 self.anchor = newAnchor                 guard let samples = newSamples as? [HKQuantitySample] else { return }                 guard !samples.isEmpty else { return }                 self.logger.debug("New data: \(samples.debugDescription)")                 for type in types {                     let filteredSamples = samples.filter({ $0.quantityType == type })                     if  !filteredSamples.isEmpty {                         self.logger.debug("\(filteredSamples.count) new \(type.debugDescription) samples")                         Task {                             do {                                 try await self.dataController.importHealthKitSample(filteredSamples, type: type)                             } catch {                                 self.logger.error("importHealthKitSample error: \(error.localizedDescription)")                             }                         }                     }                 }             }         HKStore.execute(anchoredQuery)     }
3
0
2.2k
Sep ’22
HKStatisticsCollectionQueryDescriptor document example is not executed.
let stepType = HKQuantityType(.stepCount)         let stepsThisWeek = HKSamplePredicate.quantitySample(type: stepType, predicate: thisWeek)         let yesterday = calendar.date(byAdding: .day, value: -1, to: calendar.startOfDay(for: now))         let every5 = DateComponents(minute:5)         let healthTypes = Set([             HKCategoryType.categoryType(forIdentifier: .handwashingEvent)!         ])         let sumOfStepsQuery = HKStatisticsCollectionQueryDescriptor(             predicate: stepsThisWeek,             options: .cumulativeSum,             anchorDate: endDate,             intervalComponents: every5)         do {             let updateQueue = sumOfStepsQuery.results(for: store)             // Wait for the initial results and updates.             updateQueue = Task {                 for try await results in updateQueue {                     // Use the statistics collection here.                 }             }                      } catch {             //handle error             print(error)         }
0
0
1.1k
Jun ’22
HealthKit cost
Do I have to pay when I use healthKit in my app? Would you tell me how does it cost or provide related documents? I want to know really detailed information cause the app has many users
Replies
1
Boosts
0
Views
2.1k
Activity
Apr ’22
Apple Watch Health App not launching
Hello. My Apple Watch Health App is not launching is stuck on the loading screen forever. In the debug console, This message is displayed. `SwiftUI/EnvironmentObject.swift:70: Fatal error: No ObservableObject of type WorkoutManager found. A View.environmentObject(_:) for WorkoutManager may be missing as an ancestor of this view. 2022-04-19 10:27:58.865727-0400 FitnessFriend WatchKit Extension[65428:475974] SwiftUI/EnvironmentObject.swift:70: Fatal error: No ObservableObject of type WorkoutManager found. A View.environmentObject(_:) for WorkoutManager may be missing as an ancestor of this view. (lldb)  If anybody could help, it would be greatly appreciated.
Replies
0
Boosts
0
Views
628
Activity
Apr ’22
Healthkit background delivery is not working
https://developer.apple.com/documentation/healthkit/hkhealthstore/1614175-enablebackgrounddelivery, as Apple official described the technical documentation, We can read the health data in HealthStore when the application is not started or in the Kill state, when the data in the health App is updated. But it doesn't work for me, I don't know why, I hope I can get the answer here, thank you very much! Here is my code: typealias AccessRequestCallback = (_ success: Bool, _ error: Error?) -> Void /// Helper for reading and writing to HealthKit. class HealthKitManager: NSObject {       static let shared = HealthKitManager()       private override init() {}       private let healthStore = HKHealthStore()   /// Requests access to all the data types the app wishes to read/write from HealthKit.   /// On success, data is queried immediately and observer queries are set up for background   /// delivery. This is safe to call repeatedly and should be called at least once per launch.   func requestAccessWithCompletion(completion: @escaping AccessRequestCallback) {     guard HKHealthStore.isHealthDataAvailable() else {       debugPrint("Can't request access to HealthKit when it's not supported on the device.")       return     }     let writeDataTypes = dataTypesToWrite()     let readDataTypes = dataTypesToRead()           healthStore.requestAuthorization(toShare: writeDataTypes, read: readDataTypes) { [weak self] success, error in       guard let strongSelf = self else { return }       if success {         debugPrint("Access to HealthKit data has been granted")         strongSelf.readHealthKitData()         strongSelf.setUpBackgroundDeliveryForDataTypes(types: readDataTypes)       } else {         debugPrint("Error requesting HealthKit authorization: \(error?.localizedDescription ?? "")")       }               DispatchQueue.main.async {         completion(success,error)       }     }   }     } // MARK: - Private private extension HealthKitManager {   /// Initiates an `HKAnchoredObjectQuery` for each type of data that the app reads and stores   /// the result as well as the new anchor.   func readHealthKitData() {     debugPrint("===============readHealthKitData================") //    HealthKitManager.shared.addLocalPush(title: "readHealthKitData")   }   /// Sets up the observer queries for background health data delivery.   ///   /// - parameter types: Set of `HKObjectType` to observe changes to.   private func setUpBackgroundDeliveryForDataTypes(types: Set<HKObjectType>) {     for type in types {       guard let sampleType = type as? HKSampleType else {         debugPrint("ERROR: \(type) is not an HKSampleType");         continue       }       var query: HKQuery!       query = HKObserverQuery(sampleType: sampleType, predicate: nil) { [weak self] query, completionHandler, error in         if error != nil {           debugPrint("observer query update handler called for type \(type), error: \(error?.localizedDescription ?? "")")           return         }         guard let strongSelf = self else { return }         strongSelf.queryForUpdates(type: type)         completionHandler()       }       healthStore.execute(query)       healthStore.enableBackgroundDelivery(for: type, frequency: .immediate) { success, error in         if error != nil {           debugPrint("enableBackgroundDeliveryForType handler called for \(type) - success: \(success), error: \(error?.localizedDescription ?? "")")           return         }         debugPrint("enableBackgroundDeliveryForType: \(type)")       }     }   }   /// Initiates HK queries for new data based on the given type   ///   /// - parameter type: `HKObjectType` which has new data avilable.   private func queryForUpdates(type: HKObjectType) { //    self.addLocalPush(title: "queryForUpdates")     switch type {     case HKObjectType.quantityType(forIdentifier: .bodyMass):       debugPrint("HKQuantityTypeIdentifier-BodyMass")     case HKObjectType.quantityType(forIdentifier: .height):       debugPrint("HKQuantityTypeIdentifier-Height")     case HKObjectType.quantityType(forIdentifier: .stepCount):       debugPrint("HKQuantityTypeIdentifier-StepCount")     case is HKWorkoutType:       debugPrint("HKWorkoutType")     default: debugPrint("Unhandled HKObjectType: \(type)")     }   }   /// Types of data that this app wishes to read from HealthKit.   ///   /// - returns: A set of HKObjectType.   private func dataTypesToRead() -> Set<HKObjectType> {     if #available(iOS 14.0, *) {       return Set(arrayLiteral:             HKObjectType.quantityType(forIdentifier: .bodyMass)!,             HKObjectType.quantityType(forIdentifier: .height)!,             HKObjectType.categoryType(forIdentifier: .handwashingEvent)!,             HKObjectType.quantityType(forIdentifier: .stepCount)!,             HKObjectType.quantityType(forIdentifier: .distanceCycling)!,             HKObjectType.workoutType())     } else {       return Set(arrayLiteral:             HKObjectType.quantityType(forIdentifier: .bodyMass)!,             HKObjectType.quantityType(forIdentifier: .height)!,             HKObjectType.quantityType(forIdentifier: .stepCount)!,             HKObjectType.quantityType(forIdentifier: .distanceCycling)!,             HKObjectType.workoutType())     }   }   /// Types of data that this app wishes to write to HealthKit.   ///   /// - returns: A set of HKSampleType.   private func dataTypesToWrite() -> Set<HKSampleType> {     if #available(iOS 14.0, *) {       return Set(arrayLiteral:             HKObjectType.quantityType(forIdentifier: .bodyMass)!,             HKObjectType.quantityType(forIdentifier: .height)!,             HKObjectType.categoryType(forIdentifier: .handwashingEvent)!,             HKObjectType.quantityType(forIdentifier: .stepCount)!,             HKObjectType.quantityType(forIdentifier: .distanceCycling)!,             HKObjectType.workoutType())     } else {       return Set(arrayLiteral:             HKObjectType.quantityType(forIdentifier: .bodyMass)!,             HKObjectType.quantityType(forIdentifier: .height)!,             HKObjectType.quantityType(forIdentifier: .stepCount)!,             HKObjectType.quantityType(forIdentifier: .distanceCycling)!,             HKObjectType.workoutType())     }   } } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {           window = UIWindow(frame: UIScreen.main.bounds)           let vc: ViewController = .init()     window?.rootViewController = vc     window?.makeKeyAndVisible()           healthKitManager.requestAccessWithCompletion() { success, error in       if success { print("HealthKit access granted") }       else { print("Error requesting access to HealthKit: \(error?.localizedDescription ?? "")") }     }           return true   }
Replies
1
Boosts
0
Views
1.6k
Activity
Apr ’22
how to send to healthkit setting after initial authorization
I have a non-native react app, which uses healthkit with an ionic plugin. I want to prompt the user to change the settings if he wants to enter more data after the initial authorization step. is there a way to do so?
Replies
1
Boosts
0
Views
446
Activity
May ’22
ResearchKit and Swift Package Manager
Hello Apple & ResearchKit, As ResearchKit is open source I was wondering if you could shed some light on when (or if so) ResearchKit will support the Swift Package Manager (SPM) as an alternative to forking, Cocoapods and Carthage? Or would that be a community effort? And if it is a community effort which branch should be the starting point for such a change (main?)? And would you be willing to accept a major re-organisation of the code to better fit SPM? Regards, Jens
Replies
0
Boosts
0
Views
770
Activity
Apr ’22
unable to check for update
I am trying to pair a new apple watch I got, iwatch 3 to my iphone 11 pro max and it keeps saying I am not connected to the internet which of course I am
Replies
0
Boosts
0
Views
887
Activity
May ’22
SwiftUI how to get total Sleep hours from Healthkit
I have issue to request Authorization and get the total sleep hours from HealthKit func requestAuthorization(completion: @escaping (Bool) -> Void) {           let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!     let heartRate = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!     let spo2 = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.respiratoryRate)!     let sleepHours = HKObjectType.categoryType(forIdentifier: .sleepAnalysis)     let setType = Set(arrayLiteral: sleep_type_t) //error cannot find 'sleepType' in scope ****           guard let healthStore = self.healthStore else { return completion(false) }           healthStore.requestAuthorization(toShare: [], read: [stepType,heartRate,spo2,sleepHours]) { (success, error) in       completion(success)     }         }    func getSleepHours(completion: @escaping (_ sleepHours: String?) -> Void) {     let sampleType = HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis)!           // Get all samples from the last 24 hours     let endDate = Date()     let startDate = endDate.addingTimeInterval(-1.0 * 60.0 * 60.0 * 24.0)     let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: [])     let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)     // Sleep query     let sleepQuery = HKSampleQuery(sampleType: sampleType,predicate: predicate,limit: 0,sortDescriptors: [sortDescriptor]) { (query, results, error) -> Void in             if error != nil {return}             // Sum the sleep time             var minutesSleepAggr = 0.0             if let result = results {               for item in result {                 if let sample = item as? HKCategorySample {                   if sample.value == HKCategoryValueSleepAnalysis.asleep.rawValue && sample.startDate >= startDate {                       let sleepTime = sample.endDate.timeIntervalSince(sample.startDate)                       let minutesInAnHour = 60.0                       let minutesBetweenDates = sleepTime / minutesInAnHour                       minutesSleepAggr += minutesBetweenDates                   }                 }               }               let sleepHours = Double(String(format: "%.1f", minutesSleepAggr / 60))!               let sleepHours2 = "(sleepHours)"               completion(sleepHours2)               print("*** SLEEP HOURS: (String(describing: sleepHours))")             }       }               healthStore?.execute(sleepQuery)   }
Replies
0
Boosts
0
Views
721
Activity
May ’22
Calculate daily steep from healthkit data
Hi, in our app we want to calculate a daily sleep from healthkit data and display it on a graph similar to apple health. but the sleep data that we are getting merged a data for consecutive days. how can we calculate the daily sleep data based on the healthkit sleep data? how does apple health calculate the daily sleep data?
Replies
1
Boosts
0
Views
1.2k
Activity
May ’22
HealthKit settings URL
Hello everyone. I need to find url to reach this screen in Health settings. App-Prefs:HEALTH&path= ???(In settings called 'Data Access & Device'. Somebody know where I can find right url for this one.Thank you!
Replies
1
Boosts
0
Views
1.6k
Activity
May ’22
How to mimic the way apple implements medals in their fitness app?
Hi all, I am currently making a fitness app and want to replicate the way Apple incorporate medals in their Fitness app. They have a page called awards and it looks like a collection view of different medals that the user can unlock. Once unlocking a medal the user can tap on the medal and it opens to a full screen intractable scene where the user can rotate the medal etc. I have had a play around with SceneKit and managed to get a medal loaded into a scene and display it in the app. However my functionality does not look as smooth or as polished as Apples. Does anyone have any idea on how they have managed to present all of the different Scene-kit scenes in a collection-view for example? Or how they have achieved the smooth transition between tapping on the medal in the collection-view and the scene. I guess this is created using SwiftUI. Can this be replicated in Storyboards? Thanks!
Replies
4
Boosts
0
Views
3.2k
Activity
Feb ’23
Storing Customer's Health App Data "Steps" for future rewarding
we are planning to develop a new module on our rewarding system to reward our customers on their physical activities "number of steps" received from the Apple Health and Fitness API. the customers will have to consent the access to their health app to allow the integration ofcourse. the idea is to allow the customer to participate in a weekly competition, where we'll be counting the number of steps of each participants and accordingly rewards the top 3 participants. my question here, will apple allow us to store/count the customers' number of steps after getting the proper consent. if yes, than what might be the further limitations/restrictions on processing such data?
Replies
0
Boosts
0
Views
547
Activity
Jun ’22
HealthKit - Request share and read permission of same type on separate calls
Hi. In an app, I'm calling requestAuthorization(toShare: Set([HKSampleType.workoutType()]), read: nil) if a user decides that he wants to send workouts to HealthKit and I have a separate call to requestAuthorization if the user also wants to read workouts from HealthKit -> requestAuthorization(toShare: nil, read: Set([HKSampleType.workoutType()])). The problem is that if I do this, when I do a second call for the same type but with a different permission, HealthKit is going to delete my previous permission for that type. Can't I segregate the share and read permissions of a same type in different calls to requestAuthorization? If a type can have a share and read permissions, I always need to put that type in both toShare and read parameters on every call of requestAuthorization?
Replies
0
Boosts
0
Views
419
Activity
Jun ’22
detect when hand wash event is finished
Hello :) I'm trying to make Apple Watch app that can detect hand wash is finished. I followed workout app that apple provided, and succeed in getting hand wash count information . but how can I detect hand wash event when app is not foreground or executed. my full code is as below /* See LICENSE folder for this sample’s licensing information. Abstract: The start view. */ import SwiftUI import HealthKit var healthStore: HKHealthStore!     struct StartView: View {          @State var count: Int = 0     //     //  ContentView.swift     //  handwash     //     //  Created by pedro jung on 2022/06/09.     //                  var body: some View {                 Button(action: {                     checkHealthKit()                 }, label: {                     Text("Button\(self.count)")                 })             }             func checkHealthKit() {                 print(count)                 healthStore = HKHealthStore()                 let healthTypes = Set([                     HKCategoryType.categoryType(forIdentifier: .handwashingEvent)!                 ])                 healthStore.requestAuthorization(toShare: nil, read: healthTypes)                     { (success, error) in                         fetchHandWashing()                     }             }                          func fetchHandWashing() {                 let now = Date()                 let calendar = Calendar.current                 let yesterday = calendar.date(byAdding: .day, value: -1, to: calendar.startOfDay(for: now))                 let predicate = HKQuery.predicateForSamples(withStart: yesterday, end: now, options: [])                 let sortDescriptor = [NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: true)]                 let washingEvent = HKCategoryType.categoryType(forIdentifier: .handwashingEvent)!                 let query = HKSampleQuery(sampleType: washingEvent,                                                 predicate: predicate,                                                 limit: HKObjectQueryNoLimit,                                                 sortDescriptors: sortDescriptor) {                     (query, results, error) in                     guard error == nil else { print("error"); return }                     let format = DateFormatter()                     format.dateFormat = "yyyy-MM-dd HH:mm:ss"                     format.timeZone   = TimeZone(identifier: "Asia/Tokyo")                     print("\(format.string(from: yesterday!)) - \(format.string(from: now)) r \(results)esult 🥳:")                     if let tmpResults = results as? [HKCategorySample] {                         print(tmpResults.count)                                                  self.count=tmpResults.count                         tmpResults.forEach { (sample) in                             print(sample)                         }                     }                 }                 healthStore.execute(query)                 healthStore.enableBackgroundDelivery(                       for: washingEvent,                       frequency: .immediate,                       withCompletion: { succeeded, error in                         guard error != nil && succeeded else {                             self.count = self.count+1                             //send information!                                                                              return                         }                       // Background delivery is enabled                     }                 )                 let query2 = HKObserverQuery(                   sampleType: washingEvent,                   predicate: nil,                   updateHandler: { query, completionHandler, error in                     defer {                       completionHandler()                     }                     guard error != nil else {                       return                     }                     // TODO                                      })                 healthStore.execute(query2)              }      }
Replies
0
Boosts
0
Views
877
Activity
Jun ’22
Medications in HealthKit?
Exciting to see the new Medication tracking features coming to Health. As a medical app we're wondering if read/write access to these is coming to HealthKit? We're currently building prescription management into our app so it would be great to be able to let users also add these to Health to handle their adherence tracking.
Replies
4
Boosts
9
Views
3.3k
Activity
Jun ’23
HKObserverQuery updateHandler is getting fired twice in a row
Hi, I'm trying to implement HealthKit Background delivery for my app and I'm getting a strange behavior where the HKObserverQuery updateHandler is getting fired twice. I'm running Xcode 13.4 & iOS 15.5. 2022-06-10 10:05:58.725006+0200 Cori[79737:8949689] [HealthKit] Run Background Delivery Handler 2022-06-10 10:05:58.726283+0200 Cori[79737:8949689] [HealthKit] Run Background Delivery Handler 2022-06-10 10:05:58.736475+0200 Cori[79737:8949700] [HealthKit] New data: [200 mg/dL 4680E3F5-034A-4AED-843C-9066532AD459 "Salud" (15.5), "iPhone14,2" (15.5)metadata: { 2022-06-10 10:05:58.736632+0200 Cori[79737:8949700] [HealthKit] 1 new HKQuantityTypeIdentifierBloodGlucose samples 2022-06-10 10:05:58.736926+0200 Cori[79737:8949689] [persistence] HealthKit: Start import to Core Data 2022-06-10 10:05:58.737116+0200 Cori[79737:8949700] [HealthKit] New data: [200 mg/dL 4680E3F5-034A-4AED-843C-9066532AD459 "Salud" (15.5), "iPhone14,2" (15.5)metadata: { 2022-06-10 10:05:58.737985+0200 Cori[79737:8949689] [persistence] HealthKit: 1 samples of type HKQuantityTypeIdentifierBloodGlucose not from this app! 2022-06-10 10:05:58.753583+0200 Cori[79737:8949689] [persistence] HealthKit: Start batch insert request. 2022-06-10 10:05:58.753630+0200 Cori[79737:8949700] [HealthKit] 1 new HKQuantityTypeIdentifierBloodGlucose samples 2022-06-10 10:05:58.753873+0200 Cori[79737:8949689] [persistence] HealthKit: Start import to Core Data 2022-06-10 10:05:58.754019+0200 Cori[79737:8949689] [persistence] HealthKit: 1 samples of type HKQuantityTypeIdentifierBloodGlucose not from this app! 2022-06-10 10:05:58.754076+0200 Cori[79737:8949689] [persistence] HealthKit: Start batch insert request. 2022-06-10 10:05:58.759208+0200 Cori[79737:8949701] [persistence] HealthKit: Successfully imported data. 2022-06-10 10:05:58.759669+0200 Cori[79737:8949701] [persistence] HealthKit: Successfully imported data. This is my code: App Delegate extension AppDelegate {     public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {         if settings.syncHealthKit { HealthKit.shared.setUpBackgroundDelivery()         }         return true     } HealthKit Class class HealthKit: ObservableObject {     private let logger = Logger(subsystem: "com.ChubbyApps.Diabetes", category: "HealthKit")     private var dataController: DataController = .shared     private var ajustes: AjustesModel = .shared     public let isAvailable = HKHealthStore.isHealthDataAvailable()     private lazy var isAuthorized = false     // MARK: - Properties     private var anchor: HKQueryAnchor? {         get {             guard let data = NSUbiquitousKeyValueStore.default.object(forKey: Keys.HKAnchor) as? Data else {                 return nil             }             do {                 return try NSKeyedUnarchiver.unarchivedObject(ofClass: HKQueryAnchor.self, from: data)             } catch {                 logger.error("Unable to unarchive \(data): \(error.localizedDescription)")                 return nil             }         }         set(newAnchor) {             guard let newAnchor = newAnchor else {                 return             }             do {                 let data = try NSKeyedArchiver.archivedData(withRootObject: newAnchor, requiringSecureCoding: true)                 NSUbiquitousKeyValueStore.default.set(data, forKey: Keys.HKAnchor)             } catch {                 logger.error("Unable to archive \(newAnchor): \(error.localizedDescription)")             }         }     }     // MARK: - Initializers     static let shared = HealthKit()     // MARK: - Public Methods     public func requestAuthorization() async -> Bool {         guard isAvailable else { return false }         do {             try await HKStore.requestAuthorization(toShare: types, read: types)             self.isAuthorized = true             return true         } catch let error {             self.logger.error("An error occurred while requesting HealthKit Authorization: \(error.localizedDescription)")             return false         }     }     // MARK: - Background     func setUpBackgroundDelivery() {         let query: HKObserverQuery = HKObserverQuery(sampleType: glucose, predicate: nil, updateHandler: self.backgroundDeliveryHandler)         HKStore.execute(query)         HKStore.enableBackgroundDelivery(for: glucose, frequency: .immediate) { success, error in             if success {                 self.logger.debug("Enabled background delivery of stepcount changes")             } else {                 if let theError = error {                     self.logger.debug("Failed to enable background delivery of stepcount changes. Error: \(theError.localizedDescription)")                 }             }         }     }     func backgroundDeliveryHandler(query: HKObserverQuery!, completionHandler: HKObserverQueryCompletionHandler!, error: Error!) {         self.logger.debug("Run Background Delivery Handler")         self.anchoredQueryFor(types)          completionHandler()     }     private func anchoredQueryFor(_ tipos: Set<HKSampleType>) {         var queryDescriptors = [HKQueryDescriptor]()         for type in tipos {             queryDescriptors.append(HKQueryDescriptor(sampleType: type, predicate: nil))         }         let anchoredQuery = HKAnchoredObjectQuery(             queryDescriptors: queryDescriptors,             anchor: anchor,             limit: HKObjectQueryNoLimit) { _, newSamples, _, newAnchor, error in                 if let error = error {                     self.logger.error("HKAnchoredObjectQuery error: \(error.localizedDescription)")                     return                 }                 self.anchor = newAnchor                 guard let samples = newSamples as? [HKQuantitySample] else { return }                 guard !samples.isEmpty else { return }                 self.logger.debug("New data: \(samples.debugDescription)")                 for type in types {                     let filteredSamples = samples.filter({ $0.quantityType == type })                     if  !filteredSamples.isEmpty {                         self.logger.debug("\(filteredSamples.count) new \(type.debugDescription) samples")                         Task {                             do {                                 try await self.dataController.importHealthKitSample(filteredSamples, type: type)                             } catch {                                 self.logger.error("importHealthKitSample error: \(error.localizedDescription)")                             }                         }                     }                 }             }         HKStore.execute(anchoredQuery)     }
Replies
3
Boosts
0
Views
2.2k
Activity
Sep ’22
can I use HKStatisticsCollectionQueryDescriptor to HKCategoryType
I want to query to washing event. but washing hand is HKCategoryType so I can't use HKStatiticsCollectionQueryDescriptor because it only accept HKQuantitySample. is there a way that I can use it ?
Replies
0
Boosts
0
Views
970
Activity
Jun ’22
HKStatisticsCollectionQueryDescriptor document example is not executed.
let stepType = HKQuantityType(.stepCount)         let stepsThisWeek = HKSamplePredicate.quantitySample(type: stepType, predicate: thisWeek)         let yesterday = calendar.date(byAdding: .day, value: -1, to: calendar.startOfDay(for: now))         let every5 = DateComponents(minute:5)         let healthTypes = Set([             HKCategoryType.categoryType(forIdentifier: .handwashingEvent)!         ])         let sumOfStepsQuery = HKStatisticsCollectionQueryDescriptor(             predicate: stepsThisWeek,             options: .cumulativeSum,             anchorDate: endDate,             intervalComponents: every5)         do {             let updateQueue = sumOfStepsQuery.results(for: store)             // Wait for the initial results and updates.             updateQueue = Task {                 for try await results in updateQueue {                     // Use the statistics collection here.                 }             }                      } catch {             //handle error             print(error)         }
Replies
0
Boosts
0
Views
1.1k
Activity
Jun ’22
HKQuantityTypeIdentifier Cadence
Hi. is there a explicit HKQuantityTypeIdentifier for the new Cadence value in iOS 16. I only can find in the documentation HKQuantityTypeIdentifier runningPower runningSpeed runningStrideLength runningVerticalOscillation runningGroundContactTime But nothing like runningCadence???
Replies
3
Boosts
0
Views
1.6k
Activity
Mar ’23
My mobile app "app store connect team" is not publishing
They said that due to the health features (There is a pedometer. Pharmacy and hospital locations are there.) in our application, they cannot publish it from my personal account. If we open an account on behalf of our sole proprietorship, will our application be published? Sorry for my bad English.
Replies
1
Boosts
1
Views
547
Activity
Jun ’22
Apple Health Kit Disconnect
We are building an app, and connecting Apple Health, but you are not able to disconnect it.
Replies
0
Boosts
0
Views
614
Activity
Jun ’22