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

问题描述

我正在开发 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 已获得正确授权,正如我在手表的设置中看到的那样。有任何想法吗?对我的代码有什么建议吗?

解决方法

哇,毕竟我发现了这个问题:行 previousAnchor = newAnchor 需要 after guard 语句。就是这样。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...