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)
}
我的 UITableViewController
在 UIPageViewController
。从详细信息屏幕返回时,UITableViewController
上的 viewDidAppear()
不会被调用,所以我假设 viewDidDisappear()
也不会被调用,我在那里停止了查询。我的假设是错误的。
关于在哪里停止做多的问题 运行 HKQuery
s: Do HKQuery's need to be stopped in View Controllers
我有一个 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)
}
我的 UITableViewController
在 UIPageViewController
。从详细信息屏幕返回时,UITableViewController
上的 viewDidAppear()
不会被调用,所以我假设 viewDidDisappear()
也不会被调用,我在那里停止了查询。我的假设是错误的。
关于在哪里停止做多的问题 运行 HKQuery
s: Do HKQuery's need to be stopped in View Controllers