В моем проекте я создаю HKStatisticsCollectionQueries для серии HKQuantityTypes. Затем результатыHandler добавляет эти данные в упорядоченный по дате массив объектов. Я хочу выполнить другую операцию только после обработки всей серии HKStatisticsCollectionQueries и результатов, добавленных в мой массив.HKStatisticsCollectionQuery resultsHandler and NSOperation
Я попытался сделать это, поставив задачу внутри подкласса NSOperation, но зависимый блок запускается до того, как любой из образцов будет добавлен в массив. Согласно документации HKStatisticsCollectionQuery «Этот метод выполняет запрос на анонимную очереди фона. Когда запрос завершен, он выполняет обработчик результатов на ту же фон очередь»
Есть ли способ использовать initialResultsHandler и statisticsUpdateHandler HKStatisticsCollectionQuery с NSOperation?
при запуске этого я получаю следующий вывод:
cycleOperation начать
cycleOperation CompletionBlock
dependentOperation начать
dependentOperation CompletionBlock
SumStatistics addSamplesToArray: цикл: 96 пробы добавляли
SumStatistics Основной полное: 96 образцы добавлены
func getCycleKm(){
let sampleType = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceCycling)
let hkUnit = HKUnit.meterUnitWithMetricPrefix(.Kilo)
println("cycleOperation start")
let cycleOperation = SumStatistics(quantityType: sampleType, startDate: startingDate, heathDataArray: self.healthDataArray)
cycleOperation.completionBlock = {println("cycleOperation CompletionBlock ")}
let dependentOperation = NSBlockOperation{()->Void in println("dependentOperation start")}
dependentOperation.completionBlock = {println("dependentOperation CompletionBlock")}
dependentOperation.addDependency(cycleOperation)
self.operationQueue.addOperation(cycleOperation)
self.operationQueue.addOperation(dependentOperation)
}
class SumStatistics:NSOperation{
let healthKitStore:HKHealthStore = HKHealthStore()
private let quantityType:HKQuantityType
private let startDate:NSDate
private let endDate: NSDate
private let statsOption: HKStatisticsOptions
var healthDataArray:[HealthData]
required init(quantityType:HKQuantityType, startDate:NSDate, heathDataArray:[HealthData]){
self.quantityType = quantityType
self.startDate = startDate
let startOfToday = NSDate().getStartOfDate()
self.endDate = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: 1, toDate: startOfToday, options: nil)!
self.statsOption = HKStatisticsOptions.CumulativeSum
self.healthDataArray = heathDataArray
super.init()
}
override func main() {
getSumStatistics { (hkSamples, statsError) -> Void in
self.addSamplesToArray(hkSamples)
println("SumStatistics main complete: \(hkSamples.count) samples added")
}
}
func addSamplesToArray(newSamples:[HKQuantitySample]){
var samples = newSamples
samples.sort({$0.startDate.timeIntervalSinceNow > $1.startDate.timeIntervalSinceNow})
if samples.count == 0{
println("SumStatistics addSamplesToArray: no samples!")
return
}
var ctr = 0
var typeString = ""
for healthDataDate in self.healthDataArray{
while healthDataDate.date.isSameDate(samples[ctr].startDate) && ctr < samples.count - 1{
switch samples[ctr].quantityType.identifier {
case HKQuantityTypeIdentifierBodyMass:
healthDataDate.weight = samples[ctr].quantity
typeString = "weight"
case HKQuantityTypeIdentifierDietaryEnergyConsumed:
healthDataDate.dietCalories = samples[ctr].quantity
typeString = "diet"
case HKQuantityTypeIdentifierActiveEnergyBurned:
healthDataDate.activeCalories = samples[ctr].quantity
typeString = "active"
case HKQuantityTypeIdentifierBasalEnergyBurned:
healthDataDate.basalCalories = samples[ctr].quantity
typeString = "basal"
case HKQuantityTypeIdentifierStepCount:
healthDataDate.steps = samples[ctr].quantity
typeString = "steps"
case HKQuantityTypeIdentifierDistanceCycling:
healthDataDate.cycleKM = samples[ctr].quantity
typeString = "cycle"
case HKQuantityTypeIdentifierDistanceWalkingRunning:
healthDataDate.runWalkKM = samples[ctr].quantity
typeString = "runWalk"
default:
println("SumStatistics addSamplesToArray type not found -> \(samples[ctr].quantityType)")
}
if ctr < samples.count - 1{
ctr += 1
}else{
break
}
}
}
println("SumStatistics addSamplesToArray: \(typeString): \(newSamples.count) samples added")
}
func getSumStatistics(completionHandler:([HKQuantitySample], NSError!)->Void){
let dayStart = NSCalendar.currentCalendar().startOfDayForDate(startDate)
let addDay = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: 1, toDate: endDate, options:nil)
let dayEnd = NSCalendar.currentCalendar().startOfDayForDate(addDay!) //add one day
let interval = NSDateComponents()
interval.day = 1
let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: HKQueryOptions.None)
let newQuery = HKStatisticsCollectionQuery(quantityType: quantityType,
quantitySamplePredicate: predicate,
options: statsOption,
anchorDate: dayStart,
intervalComponents: interval)
newQuery.initialResultsHandler = {
query, statisticsCollection, error in
var resultsArray = [HKQuantitySample]()
if error != nil {
println("*** An error occurred while calculating the statistics: \(error.localizedDescription) ***")
}else{
statisticsCollection.enumerateStatisticsFromDate(self.startDate, toDate: self.endDate, withBlock: { (statistics, stop) -> Void in
if let statisticsQuantity = statistics.sumQuantity() {
let startD = NSCalendar.currentCalendar().startOfDayForDate(statistics.startDate)
let endD = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: 1, toDate: startD, options: nil)
let qSample = HKQuantitySample(type: self.quantityType, quantity: statisticsQuantity, startDate: startD, endDate: endD)
resultsArray.append(qSample)
}
})
}
completionHandler(resultsArray,error)
}
newQuery.statisticsUpdateHandler = {
query, statistics, statisticsCollection, error in
println("*** updateHandler fired")
var resultsArray = [HKQuantitySample]()
if error != nil {
println("*** An error occurred while calculating the statistics: \(error.localizedDescription) ***")
}else{
statisticsCollection.enumerateStatisticsFromDate(self.startDate, toDate: self.endDate, withBlock: { (statistics, stop) -> Void in
if let statisticsQuantity = statistics.sumQuantity() {
let startD = NSCalendar.currentCalendar().startOfDayForDate(statistics.startDate)
let endD = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitDay, value: 1, toDate: startD, options: nil)
let qSample = HKQuantitySample(type: self.quantityType, quantity: statisticsQuantity, startDate: startD, endDate: endD)
resultsArray.append(qSample)
}
})
}
completionHandler(resultsArray,error)
}
self.healthKitStore.executeQuery(newQuery)
}
}