HKAnchoredObjectQuery updateHandler 未被调用

HKAnchoredObjectQuery updateHandler not being called

我有一个 UITableView 支持 HKAnchoredObjectQuery。我的 resultsHandler 调用正常,但我的 updateHandler 从未调用过。我不是在寻找后台交付,只是在将新样本添加到健康商店时进行实时前台交付。根据 updateHandler 上的文档:

If this property is set to nil, the anchor query automatically stops as soon as it has finished calculating the initial results. If this property is not nil, the query behaves similarly to the observer query. It continues to run, monitoring the HealthKit store. If any new, matching samples are saved to the store—or if any of the existing matching samples are deleted from the store—the query executes this update handler on a background queue.

我确实在查询中设置了 updateHandler,并且有新样本写入健康存储。

在我的 viewDidLoad 中,我设置了我的查询:

override func viewDidLoad() {
    super.viewDidLoad()

    // Setup TableView
    tableView.dataSource = self
    tableView.delegate = self

    let calendar = Calendar.current
    let nextDay = calendar.date(byAdding: .day, value: 1, to: self.date)!
    let startOfNextDay = calendar.startOfDay(for: nextDay)

    let resultsHandler: HKAnchoredObjectQueryHandler = { [weak self](query, samples, deletedObjects, anchor, error) in
        guard let strongSelf = self else { return }
        guard let samples = samples as? [HKCorrelation],
            let _ = deletedObjects else {
                // Need error handling here
                return debugPrint("Query error occurred: \(error!.localizedDescription)")
            }

        DispatchQueue.main.async {
            // Get a reference to the query and anchor
            strongSelf.query = query
            strongSelf.anchor = anchor

            // Add new samples
            strongSelf.foodEntries = samples
            for entry in strongSelf.foodEntries {
                debugPrint(entry.metadata?[HKMetadataKey.mealOfDay] as! Int)
            }
        }
    }

    let updateHandler: HKAnchoredObjectQueryHandler = {[weak self](query, samples, deletedObjects, anchor, error) in
        guard let strongSelf = self else { return }
        guard let samples = samples as? [HKCorrelation],
            let deletedObjects = deletedObjects else {
                // Need error handling here
                return debugPrint("Query error occurred: \(error!.localizedDescription)")
        }

        DispatchQueue.main.async {
            // Get a reference to
            strongSelf.anchor = anchor
            print(#line, "HKAnchoredObjectQuery IS LONG RUNNING")
            // Add new samples
            strongSelf.foodEntries.append(contentsOf: samples)

            // Remove deleted samples
            let deletedObjects = deletedObjects
            for object in deletedObjects {
                if let index = strongSelf.foodEntries.index(where: {[=10=].uuid == object.uuid} ) {
                    strongSelf.foodEntries.remove(at: index)
                }
            }
            strongSelf.tableView.reloadData()
        }
    }

    HealthManager.shared.anchoredFoodQuery(startDate: self.date, endDate: startOfNextDay, anchor: anchor, resultsHandler: resultsHandler, updateHandler: updateHandler)

}

我的 HealthManager 中的锚定对象方法是:

func anchoredFoodQuery(startDate: Date, endDate: Date, anchor: HKQueryAnchor? = nil, resultsHandler: @escaping HKAnchoredObjectQueryHandler, updateHandler: HKAnchoredObjectQueryHandler?) {
    let predicate = HKSampleQuery.predicateForSamples(withStart: startDate, end: endDate, options: [.strictStartDate, .strictEndDate]) //NSPredicate(format: "date => %@ && date < %@", startDate as NSDate, endDate as NSDate)
    guard let foodIdentifier = HKCorrelationType.correlationType(forIdentifier: .food) else {
        fatalError("Can't make food Identifier")
    }
    anchoredQuery(for: foodIdentifier, predicate: predicate, resultsHandler: resultsHandler, updateHandler: updateHandler)
}

/// Wrapper to create and execute a query
private func anchoredQuery(for sampleType: HKSampleType, predicate: NSPredicate?, anchor: HKQueryAnchor? = nil, limit: Int = HKObjectQueryNoLimit, resultsHandler: @escaping HKAnchoredObjectQueryHandler , updateHandler: HKAnchoredObjectQueryHandler?) {
    let query = HKAnchoredObjectQuery(type: sampleType,
                                      predicate: predicate,
                                      anchor: anchor,
                                      limit: limit,
                                      resultsHandler: resultsHandler)
    query.updateHandler = updateHandler

    healthStore.execute(query)
}

我的 UITableViewControllerUIPageViewController。从详细信息屏幕返回时,UITableViewController 上的 viewDidAppear() 不会被调用,所以我假设 viewDidDisappear() 也不会被调用,我在那里停止了查询。我的假设是错误的。

关于在哪里停止做多的问题 运行 HKQuerys: Do HKQuery's need to be stopped in View Controllers