Jake
Jake

Reputation: 1

How to get headphone audio level data from Apple Health

What is wrong with this code?

func main() {

var totalDuration: TimeInterval = 0

// Check if HealthKit is available on the device
 guard HKHealthStore.isHealthDataAvailable() else {
    print("HealthKit is not available on this device.")
    // Handle the error or return from the function
    return
}
print("HealthKit is available on this device.")

// Create an instance of HKHealthStore
let healthStore = HKHealthStore()

// Define the headphone audio category
guard let audioCategory = HKObjectType.categoryType(forIdentifier: .audioExposureEvent) else {
    print("Unable to create the audio exposure category type.")
    // Handle the error or return from the function
    return
}

// Request authorization from the user to access headphone audio data
healthStore.requestAuthorization(toShare: nil, read: [audioCategory]) { (success, error) in
    guard success else {
        if let error = error {
            print("Failed to request authorization: \(error.localizedDescription)")
        }
        // Handle the error or return from the function
        return
    }
    
    // Define the predicate to query the audio data for AirPods
    
   let airPodsPredicate = HKQuery.predicateForObjects(withMetadataKey: HKMetadataKeyDeviceManufacturerName, operatorType: .equalTo, value: "Apple")
    
    
    // Define the query to retrieve the audio data
    let query = HKSampleQuery(sampleType: audioCategory, predicate: nil, limit: HKObjectQueryNoLimit, sortDescriptors: nil) { (query, samples, error) in
        guard let audioSamples = samples as? [HKCategorySample] else {
            if let error = error {
                print("Failed to retrieve audio samples: \(error.localizedDescription)")
            }
            // Handle the error or return from the function
            return
        }
        
        //var totalDuration: TimeInterval = 0
        
        // Calculate the total duration of audio played by AirPods
        for sample in audioSamples {
            totalDuration += sample.endDate.timeIntervalSince(sample.startDate)
            print("+")
        }
        
        // Print the total duration in seconds
        
    }
    
    // Execute the query
    healthStore.execute(query)
    print("Total duration of audio played by AirPods: \(totalDuration) seconds")
}

}

I tried to get the total time of audio played with AirPods. The code can be executed on my iPhone but the result is always 0.0 seconds, which is just impossible. The problem even occurs with more general attempts trying to get data that is not device specific. Also tried different Identifiers of HKObjectType.categoryType. I don't get any + printed. Any ideas? Thank you

Upvotes: -1

Views: 88

Answers (1)

gggava
gggava

Reputation: 266

You are using .audioExposureEvent which is deprecated. If you want to get the total amount of Audio Exposure using a Headphone, then you should use .headphoneAudioExposure

You can use HKStatisticalQuery to do this work for you in a simpler way. Use the .duration option to get the aggregation of the duration of your samples.

func getTotalHeadphoneExposure() {
    let startDate = Calendar(identifier: .gregorian).date(byAdding: .year, value: -1, to: .now)!
    let endDate = Date()
    let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: [.strictStartDate])
    
    let query = HKStatisticsQuery(
        quantityType: HKQuantityType.quantityType(forIdentifier: .headphoneAudioExposure)!,
        quantitySamplePredicate: predicate,
        options: .duration
    ) { query, statistics, error in
        guard let statistics = statistics else {
            print(error!)
            return
        }
        let totalSeconds = statistics.duration()!.doubleValue(for: .second())
        print(totalSeconds)
    }
    HKHealthStore().execute(query)
}

Documentation on statistical queries: https://developer.apple.com/documentation/healthkit/queries/executing_statistical_queries/

Upvotes: 1

Related Questions