如何从 healthkit 框架中读取上次更新的洗手数据?

Posted

技术标签:

【中文标题】如何从 healthkit 框架中读取上次更新的洗手数据?【英文标题】:How to read last updated hand-wash data from healthkit framework? 【发布时间】:2020-12-03 10:10:11 【问题描述】:

我使用以下代码从 healthkit 中获取洗手数据。我使用下面的查询/示例数据查询来检索上次更新的洗手数据,但返回 nil。

func readMostRecentSample(for type: HKSampleType, completion: @escaping (HKQuantitySample?, Error?) -> Void) 
            print("read query function calling")
            let predicate = HKQuery.predicateForSamples(withStart: Date.distantPast, end: Date(), options: .strictEndDate)
            let mostRecentSortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
            let sampleQuery = HKSampleQuery(sampleType: type, predicate: predicate, limit: 1, sortDescriptors: [mostRecentSortDescriptor])  (query, result, error) in
                
                DispatchQueue.main.async 
                    guard let samples = result as? [HKQuantitySample], let sample = samples.first else 
                        completion(nil, error)
                        print("HKit error: \(String(describing: error?.localizedDescription))")
    
                        return
                    
                    completion(sample, nil)
                    print("read HKsample :: \(sample.quantity)")
                    print("read HKsample :: \(sample.quantityType)")
    
                
            
            print("read query end calling")
    
            healthStore.execute(sampleQuery)
            

    HealthKitDataStore.sharedInstance.readMostRecentSample(for: handWashCount)  (sample, error) in
                    
                    print("hand_washError \(String(describing: error?.localizedDescription))")

                
                print("hand_washsampledata \(sample.debugDescription)")
                if let sample = sample
                    
                    self.patientVital.hand_wash = "\(sample.quantity.doubleValue(for: HKUnit.init(from: "count/day")))"
                    print("hand_wash\(sample.count)")
                    print("hand_wash\(sample.quantity.is(compatibleWith: HKUnit.init(from: "count/day")))")
                    print("hand_wash\(sample.quantity.is(compatibleWith: HKUnit.init(from: "count/day")))")
    
                    print("hand_wash: \(self.patientVital.pulsebpm ?? "no data")")
                
            

没有收到数据。 请对此提供一些见解...

【问题讨论】:

【参考方案1】:

我知道这已经很晚了,但发布这可能会帮助其他正在寻求解决方案的人。

洗手事件是HKCategory 的实例,因此样本是HKCategorySample 的对象。但你想成为HKQuantitySample

这是我尝试过的,它按预期工作。

public struct HealthDataManager 
    private let healthStore: HKHealthStore

    public static let shared = HealthDataManager()

    public init() 
        healthStore = HKHealthStore()
    

    public func readRecentHandWash(for date: Date, completion: @escaping (HKSample?, Error?) -> Void) 
    
        guard HKHealthStore.isHealthDataAvailable() else 
            print("Healthkit is not available.")
            return
        
    
        guard let handWash = HKCategoryType.categoryType(forIdentifier: HKCategoryTypeIdentifier.handwashingEvent) else 
            fatalError("*** Unable to get handwashingEvent on this device ***")
        
    
        healthStore.requestAuthorization(toShare: nil, read: [handWash])  (success, error) in
                        
            let predicate = HKQuery.predicateForSamples(withStart: Date.distantPast, end: Date(), options: .strictEndDate)
            let query = HKSampleQuery(sampleType: handWash,
                                      predicate: predicate,
                                      limit: HKObjectQueryNoLimit,
                                      sortDescriptors: [NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)])  (query, samples, error) in
                
                DispatchQueue.main.async 
                    
                    if let err = error 
                        completion(nil, err)
                     else 
                        guard let actualSamples = samples else 
                            completion(nil, error) // Here you will not get any error, but you have no data, so you have to pass custom error object that shows no data found.
                            return
                        
                        
                        completion(actualSamples.first, nil)
                    
                
            
            healthStore.execute(query)
        
    

当你应该调用这个方法时:

HealthDataManager.shared.readRecentHandWash(for: Date())  (sample, error) in
        
    var str = ""
        
    if let washSample = sample as? HKCategorySample 
                                
        str = str.appendingFormat("\n\(washSample.categoryType)")
        let diffComponents = Calendar.current.dateComponents([.minute, .second], from: washSample.startDate, to: washSample.endDate)
        let minutes = diffComponents.minute
        let seconds = diffComponents.second

        if let mins = minutes, mins > 0 
            str = str + " : " + "\(mins)" + " min"
            if let secs = seconds, secs > 0 
                str = str + " " + "\(secs)" + " secs"
            
         else if let secs = seconds, secs > 0 
            str = str + " : " + "\(secs)" + " secs"
        
            
        print("Most Recent : ", str)
    

【讨论】:

以上是关于如何从 healthkit 框架中读取上次更新的洗手数据?的主要内容,如果未能解决你的问题,请参考以下文章

HealthKit 读取数据心率和血压“同步后的最新更新”

HealthKit 读取数据心率和血压“同步后的最新更新”

如何使用 Xamarin Forms 从 HealthKit 读取 ECG 数据

如何使用 Xamarin Forms 从 HealthKit 读取 ECG 数据

如何通过 healthkit 使用 Apple Watch 心率更新 iOS 应用程序? (HealthKit 同步)

如何检查 HealthKit 中是不是允许读取步骤权限?