'How to handle multiple queries of different HKQuantityTypeIdentifier

I'm trying to get multiple types of health data all with the same timeframe. My problem relies on the way that I should handle all the data that I get from those queries. Currently my model is as follows:

struct DailyData {
    var steps: Int?
    var distance: Int?
    var calories: Int?
    var exercise: Int?
}

class UserData {
    let healthManager = HealthKitManager.shared
    var dailyData = [DailyData]?
    .
    .
    .
}

if I'm not mistaken, I can only query only one HKQuantityIdentifier at a time, so that means I need to call my getData() function from my HealthKitManager.swift once for every HKQuantityType that I have in my model:

func getData(type: HKQuantityTypeIdentifier, unit: HKUnit, days: Int, completed: @escaping (Result<[Int], Error>) -> Void) {
        let calendar = NSCalendar.current
        let interval = NSDateComponents()
        interval.day = 1
        
        let quantityType = HKQuantityType.quantityType(forIdentifier: type)!
        
        var anchorComponents = calendar.dateComponents([.day, .month, .year], from: NSDate() as Date)
        anchorComponents.hour = 0
        let anchorDate = calendar.date(from: anchorComponents)
        
        // Define 1-day intervals starting from 0:00
        let query = HKStatisticsCollectionQuery(quantityType: quantityType,
                                                quantitySamplePredicate: nil,
                                                options: .cumulativeSum,
                                                anchorDate: anchorDate!,
                                                intervalComponents: interval as DateComponents)
        query.initialResultsHandler = {query, results, error in
            if let error = error {
                completed(.failure(error))
                return
            }
            
            let endDate = NSDate()
            let startDate = calendar.date(byAdding: .day, value: -(days - 1), to: endDate as Date, wrappingComponents: false)
            var completeDataArray: [Int] = []
            if let myResults = results{
                myResults.enumerateStatistics(from: startDate!, to: endDate as Date) { statistics, stop in
                    if let quantity = statistics.sumQuantity(){
                        let dayData = quantity.doubleValue(for: unit)
                        completeDataArray.append(Int(dayData))
                    }
                }
            }
            completed(.success(completeDataArray))
        }
        healthStore.execute(query)
    }

My problem is that I can't find a way to correctly set the received data into my model. Could someone point me in the right direction? I believe my model could be wrong, because as for what I have gather online, it's impossible to query multiple HKQuantityTypes in one query. Meaning that I would definitely have to set my model one [Int] of a HKtype at a time.

But with what I currently have, that would mean that when the first query returns I have to create multiple DailyData objects with almost all of the variables nil except the one I'm setting. Then, when the other queries return, I should do some array checking of dailyData matching the .count values with the one I got from the query, and that just feels wrong in my opinion. Not very elegant.

I tried another approach. Instead of having an array of a custom type, having a custom type that inside has an array of ints for every HKType that I need. But this has another problem: How could I "Keep in sync" the data from every HKType? having different arrays for every type would be, in my opinion, difficult to handle for example in a tableView. How could I set number of rows in section? Which type should I prefer? Also I would be accessing data over array indexes which may lead to bugs difficult to solve.

struct WeekData {
    var steps: [Int]?
    var distance: [Int]?
    var calories: [Int]?
    var exercise: [Int]?
}

class UserData {
    let healthManager = HealthKitManager.shared
    var weekData = WeekData()
    .
    .
    .
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source