无法使用锚定查询获取重量样本

Posted

技术标签:

【中文标题】无法使用锚定查询获取重量样本【英文标题】:Can't get weight samples using anchored query 【发布时间】:2021-04-28 10:09:22 【问题描述】:

我正在开发一个 watchOS 应用程序,这是我的第一个 Swift/ios 项目。我想获取最新的体重样本并将其用于一些计算。结果呈现给用户。添加新示例后,我也想更新我的 UI。它适用于全新的模拟器安装。只要我在 iOS 模拟器中添加示例,应用程序就会在 watchOS 模拟器中更新其 UI。但是,它在我的真实设备上或重置 watchOS 模拟器后不起作用。我只是不知道为什么。 HKAnchoredObjectQuery 只返回 0 样本,但我肯定有一些样本存储在健康中。我什至可以在手表上的Settings > Health 下看到它们。我无法想象这与我的代码有关,但这里是:

class WeightProvider: ObservableObject 
    private static let weightSampleType = HKSampleType.quantityType(forIdentifier: .bodyMass)!
    private static let healthStore: HKHealthStore = .init()

    private var previousAnchor: HKQueryAnchor?
    private var runningQuery: HKAnchoredObjectQuery?

    @Published var bodyWeight: Measurement<UnitMass>?

    func getBodyWeight(longRunning: Bool = false) 
        let query = HKAnchoredObjectQuery(type: Self.weightSampleType, predicate: nil, anchor: previousAnchor, limit: longRunning ? HKObjectQueryNoLimit : 1, resultsHandler: processQueryResult)

        if longRunning 
            query.updateHandler = processQueryResult
            runningQuery = query
        

        Self.healthStore.execute(query)
    

    func stopLongRunningQuery() 
        if let runningQuery = runningQuery 
            Self.healthStore.stop(runningQuery)
            self.runningQuery = nil
        
    

    private func processQueryResult(_: HKAnchoredObjectQuery, samples: [HKSample]?, _: [HKDeletedObject]?, newAnchor: HKQueryAnchor?, error: Error?) 
        guard let samples = samples as? [HKQuantitySample], error == nil else 
            fatalError(error?.localizedDescription ?? "Failed to cast [HKSample] to [HKQuantitySample]")
        

        previousAnchor = newAnchor

        guard let sample = samples.last else 
            return
        

        DispatchQueue.main.async 
            if Locale.current.usesMetricSystem 
                let weight = sample.quantity.doubleValue(for: .gramUnit(with: .kilo))
                self.bodyWeight = .init(value: weight, unit: UnitMass.kilograms)
             else 
                let weight = sample.quantity.doubleValue(for: .pound())
                self.bodyWeight = .init(value: weight, unit: UnitMass.pounds)
            
        
    


// MARK: - HealthKit Authorization

extension WeightProvider 
    private static let typesToRead: Set<HKObjectType> = [
        weightSampleType,
    ]

    func authorize(completion: @escaping (Bool, Error?) -> Swift.Void) 
        Self.healthStore.requestAuthorization(toShare: nil, read: Self.typesToRead)  success, error in
            completion(success, error)
        
    

在我的观点onAppear 我称之为这个函数:

private func authorizeHealthKit() 
    guard firstRun else 
        return
    
    firstRun = false

    weightProvider.authorize  success, error in
        guard success, error == nil else 
            return
        

        weightProvider.getBodyWeight(longRunning: true)
    

我可以在手表的设置中看到,HealthKit 已得到正确授权。有任何想法吗?对我的代码有什么一般的提示吗?

【问题讨论】:

能否请您在 ExtensionDelegate 中添加 authorizeHealthKit 功能并重试? 不会改变任何东西。 authorizeHealthKit 在两种情况下都能正常运行,但我没有得到体重。 您能否参考此链接以获取 bodyMass 虽然它不使用 HKAnchoredObjectQuery:raywenderlich.com/… 这对我有用,我有 HKSampleQuery 和 HKObserverQuery 的组合。有些东西,HKAnchoredObjectQuery 应该真正解决。 【参考方案1】:

哇,经过这么长时间我发现了问题:previousAnchor = newAnchor 行需要 guard 语句之后。就是这样。

【讨论】:

以上是关于无法使用锚定查询获取重量样本的主要内容,如果未能解决你的问题,请参考以下文章

无法锚定到不是父项或同级 QML QtQuick 的项目

无法在 UICollectionViewCell 中锚定 UIImageVIew(以编程方式)

如何以渐进方式使用 Health Kit 样本查询

Segue Popover 无法正常运行

sample.int(m, k) 中的错误:无法获取大于总体的样本

通过 disassemble manucaftures 库从蓝牙 le scale 获取重量数据