HKAnchoredObjectQuery updateHandler未被调用

时间:2017-01-24 15:01:23

标签: ios health-kit

我有一个由UITableView支持的HKAnchoredObjectQuery。我的resultsHandler被称为罚款,但我的updateHandler从未被调用过。我不是在寻找背景交付,只是在将新样本添加到健康商店时进行实时前台交付。根据{{​​3}}上的文档:

  

如果此属性设置为nil,则锚点查询会自动停止   一旦完成计算初始结果。如果这   property不是nil,查询的行为与观察者类似   查询。它继续运行,监控HealthKit商店。如果有的话   新的匹配样本将保存到商店 - 或者任何现有的样本   匹配样本将从商店中删除 - 查询执行此操作   在后台队列上更新处理程序。

我在查询上设置了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: {$0.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)
}

1 个答案:

答案 0 :(得分:0)

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

关于在何处停止长时间运行的问题HKQueryDo HKQuery's need to be stopped in View Controllers