使用HealthKit卡在完成处理程序/调度组上

问题描述 投票:1回答:1

我有一个在类的初始化中调用的函数:

doLongTask(forPast: 6)

这是我与调度小组一起创建的游乐场:

//MAKE THE STRUCT
struct Calorie: Identifiable {

    private static var idSequence = sequence(first: 1, next: {$0 + 1})

    var id: Int
    var day: Date
    var activeCal: CGFloat
    var restingCal: CGFloat
    var dietaryCal: CGFloat

    init?(id: Int, day: Date, activeCal:CGFloat, restingCal:CGFloat, dietaryCal:CGFloat) {
        guard let id = Calorie.idSequence.next() else { return nil}
        self.id = id
        self.day = day
        self.activeCal = activeCal
        self.restingCal = restingCal
        self.dietaryCal = dietaryCal
    }
}

//CREATE HEALTHSTORE
let healthStore = HKHealthStore()

//MAKE TEST ARRAY
var testCalorieArray = [Calorie]()


func doLongTask(forPast days: Int) {

    print("Enter the function!")
    print("---")

    func getTempEnergy (for type:HKQuantityType!, unit u:HKUnit!, start fromDate:Date, end endDate:Date, completion: @escaping (Double) -> Void) {

        let countQuantityType = type

        let predicate = HKQuery.predicateForSamples(withStart: fromDate, end: endDate, options: .strictStartDate)

        let query = HKStatisticsQuery(quantityType: countQuantityType!, quantitySamplePredicate: predicate, options: .cumulativeSum) { (_, result, error) in

            var resultCount = 0.0

            guard let result = result else {
                return
            }

            if let sum = result.sumQuantity() {
                resultCount = sum.doubleValue(for: u)
            }

            DispatchQueue.main.async {
                print(resultCount)
                completion(resultCount)
            }


            }
        healthStore.execute(query)
    }


    let queue = DispatchQueue(label: "com.WILDFANGmedia.queues.serial")
    let group = DispatchGroup()

    let now = Calendar.current.startOfDay(for: Date())

    //Initialize to test values to see if they get overwritten
    var _activeEnergyBurned:CGFloat = 99.9
    var _restingEnergyBurned:CGFloat = 99.9
    var _dietaryEnergyConsumed:CGFloat = 99.9


    //EACH DAY
    for day in 0...days {

        group.enter()
        queue.async(group: group) {

            // Start und Enddatum
            let fromDate = Calendar.current.date(byAdding: .day, value: -day-1, to: now)!
            let endDate = Calendar.current.date(byAdding: .day, value: -day, to: now)!

            getTempEnergy(for: HKQuantityType.quantityType(forIdentifier: .activeEnergyBurned), unit: HKUnit.kilocalorie(), start: fromDate, end: endDate, completion: { (activeEnergyBurned) in
                print(activeEnergyBurned)
                _activeEnergyBurned = CGFloat(activeEnergyBurned)
            })

            print("End Datum: \(endDate)")
            print("Active Cal: \(_activeEnergyBurned)")

            print("Day \(day) done")
            print("---")

            testCalorieArray.append(Calorie(id: 1, day: endDate, activeCal: CGFloat(_activeEnergyBurned), restingCal: CGFloat(_restingEnergyBurned), dietaryCal: CGFloat(_dietaryEnergyConsumed))!)
            group.leave()
        }
    }


    //SHOW WHAT'S IN THE ARRAY
    group.notify(queue: queue) {

        print("All tasks done")
        print(testCalorieArray)
        print("---")
    }

    //AFTER LOOP, GO ON WITH BUSINESS
    print("Continue execution immediately")
}


doLongTask(forPast: 6)

print("AFTER THE FUNCTION")

//TEST LOOP TO RUN LONGER
for i in 1...7 {
    sleep(arc4random() % 2)
    print("Outter Row Task \(i) done")
}

print(testCalorieArray)

它应该做的是进行HKStatisticsQuery调用(以后将有3个调用)并将结果写回到我的数组中。

但是,它在函数完成之前将其写入数组,因此不会返回正确的值。我尝试了调度组,但被卡住了。

print(value)的完成处理程序中的getEnergyTemp()在测试循环结束后立即打印出来,并打印出正确的值。

我要去哪里错了?我以为我已经理解了这个原理,但是我无法使它生效。

swift grand-central-dispatch healthkit
1个回答
2
投票

主要问题是您在错误的位置拨打了leave。因此,而不是:

© www.soinside.com 2019 - 2024. All rights reserved.