Swift 2d массив пуст после вызова функции HealthKit - проблемы с потоками - PullRequest
1 голос
/ 26 июня 2019

Я заполняю двумерный массив данными HealthKit. Он работает нормально, пока функция проходит через 30 дней. вне этой функции массив пуст, потому что HealthKit данные загружаются в фоновом режиме, а все остальное выполняется раньше.

Как мне дождаться загрузки данных, чтобы я мог получить доступ к данным внутри массивов?

Вот что происходит внутри моего ViewController

            print("function call starting") // 1
        // Populate 2DArrays
        self.hkManager.getTotalCalories(forDay: 30) {caloriesValue, date   in
            //check if caloriesValue is nil, only do something if it's not
            guard let caloriesValue = caloriesValue else { return }
            let dateValue = DateFormatter.localizedString(from: date!, dateStyle: .short, timeStyle: .none)
            print("will append") // 7 (31x)
            self.caloriesArray.append([(dateValue,caloriesValue)])
    }

        print("function call done") // 2
        print(self.caloriesArray.count) // 3

        hkManager.getWeightData(forDay: 30) {bodyMassValue, date   in
            // Check if bodyMassValue is nil, only do something, if it's not
            guard let bodyMassValue = bodyMassValue else { return }
            let dateValue = DateFormatter.localizedString(from: date!, dateStyle: .short, timeStyle: .none)
            self.bodyMassArray.append([(dateValue,bodyMassValue)])
        }

        do {
            self.age = try hkManager.getAge()
        } catch let error {
            print("Error calculating age: \(error)")
        }

        print(bodyMassArray) // 4
        print(caloriesArray) // 5
        print(age!) // 6
}

Я добавил числа позади операторов print, чтобы прояснить, что выполняется, когда.

Функции, которые я вызываю, выглядят так:

    func getTotalCalories(forDay days: Int, completion: @escaping ((_ calories: Int?, _ date: Date?) -> Void)) {
    // Getting quantityType as .dietaryCaloriesConsumed
    guard let calories = HKObjectType.quantityType(forIdentifier: .dietaryEnergyConsumed) else {
        print("*** Unable to create a dietaryEnergyConsumed type ***")
        return
    }

    let now = Date()
    let startDate = Calendar.current.date(byAdding: DateComponents(day: -days), to: now)!
    var interval = DateComponents()
    interval.day = 1

    var anchorComponents = Calendar.current.dateComponents([.day, .month, .year], from: now)
    anchorComponents.hour = 0
    let anchorDate = Calendar.current.date(from: anchorComponents)!

    let query = HKStatisticsCollectionQuery(quantityType: calories,
                                            quantitySamplePredicate: nil,
                                            options: [.cumulativeSum],
                                            anchorDate: anchorDate,
                                            intervalComponents: interval)
    query.initialResultsHandler = { _, results, error in
        guard let results = results else {
            print("ERROR")
            return
        }

        results.enumerateStatistics(from: startDate, to: now) { statistics, _ in
            DispatchQueue.main.async {
                if let sum = statistics.sumQuantity() {
                    let calories = Int(sum.doubleValue(for: HKUnit.kilocalorie()).rounded())
                    completion(calories, statistics.startDate)
                    return
                }
            }
        }
    }
    healthStore.execute(query)
}

У кого-нибудь есть идеи, что мне нужно делать? Спасибо! :)

...