ios - HKStatisticsCollectionQuery resultsHandler and NSOperation -
in project creating hkstatisticscollectionqueries series of hkquantitytypes. resultshandler adds data date-ordered array of objects. want operation when entire series of hkstatisticscollectionqueries have been processed , results appended array.
i have tried putting task inside of subclass of nsoperation, dependent block fired before of samples added array. according hkstatisticscollectionquery documentation "this method runs query on anonymous background queue. when query complete, executes results handler on same background queue"
is there way use hkstatisticscollectionquery's initialresultshandler , statisticsupdatehandler nsoperation?
when run following output:
cycleoperation start
cycleoperation completionblock
dependentoperation start
dependentoperation completionblock
sumstatistics addsamplestoarray: cycle: 96 samples added
sumstatistics main complete: 96 samples added
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 = "" 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 1 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("*** error occurred while calculating 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("*** error occurred while calculating 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) }
}
the short answer rtfm! (more carefully). leaving original question , code is, , adding solution here.
thanks post helping me figure out: http://szulctomasz.com/ios-second-try-to-nsoperation-and-long-running-tasks/ , of course, found, there no substitute careful reading of reference: https://developer.apple.com/library/ios/documentation/cocoa/reference/nsoperation_class/
the problem was not subclassing nsoperation running concurrent operations. 1 must add concurrent operations start() rather main() , use kvo update finished , executing properties, signals operation complete.
i needed modify class above include:
private var _executing = false private var _finished = false override var executing:bool{return _executing} override var finished:bool{return _finished} override func cancel() { super.cancel() finish() } override func start() { if cancelled{ finish() return } willchangevalueforkey("isexecuting") _executing = true didchangevalueforkey("isexecuting") getsumstatistics { (hksamples, statserror) -> void in println("loadstatistics getstatistics completion: \(hksamples.count) samples") self.addsamplestoarray(hksamples, completionhandler: { (success) -> void in println("loadstatistics addsamplestoarray completion") self.finish() }) self.completion(true) } main() } func finish(){ willchangevalueforkey("isexecuting") willchangevalueforkey("isfinished") _executing = false _finished = true didchangevalueforkey("isexecuting") didchangevalueforkey("isfinished") } override func main() { if cancelled == true && _finished != false{ finish() return } }
now get!
cycleoperation start
loadstatistics getstatistics completion: 97 samples
loadstatistics addsamplestoarray completion
cycleoperation completionblock
dependentoperation start
dependentoperation completionblock
Ios - Hkstatisticscollectionquery Resultshandler And Nsoperation - >>>>> Download Now
ReplyDelete>>>>> Download Full
Ios - Hkstatisticscollectionquery Resultshandler And Nsoperation - >>>>> Download LINK
>>>>> Download Now
Ios - Hkstatisticscollectionquery Resultshandler And Nsoperation - >>>>> Download Full
>>>>> Download LINK Og