我有一个由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)
}
答案 0 :(得分:0)
我的UITableViewController
位于UIPageViewController
。从详细信息屏幕返回时,viewDidAppear()
上的UITableViewController
没有被调用,所以我认为viewDidDisappear()
也不会被调用,我在那里停止查询。我的假设是错误的。
关于在何处停止长时间运行的问题HKQuery
:Do HKQuery's need to be stopped in View Controllers