HKMetadataKeyTimeZone siempre es nulo para los datos de salud creados por la aplicación Health de Apple - HealthKit - iOS
Estoy leyendo los datos de salud del usuario usando HealthKit. Intentando obtener la información de la zona horaria de los datos de Salud para identificar en qué zona horaria exacta ha ocurrido la actividad de salud. Para esto, estoy dependiendo de la clave 'HKMetadataKeyTimeZone' de los metadatos de HealthKit. Pero el valor de la clave 'HKMetadataKeyTimeZone' siempre es nulo, incluso para los datos de salud que la aplicación Health de Apple registra automáticamente. Mismo problema para los datos que se ingresan manualmente en la aplicación Health de Apple.
Entonces, ¿hay alguna otra clave / forma que pueda proporcionar la información de zona horaria para cada muestra?
¿O la aplicación de salud de Apple no registra en absoluto la información de la zona horaria para los datos de salud?
¿o la aplicación de salud de Apple está registrando la información de la zona horaria para datos de salud y no la está dando a los desarrolladores a través del marco HealthKit?
La siguiente publicación de blog dice:samples retrieved from HealthKit do not have time zone information associated with them, unless the creating application captures that information in the metadata property using the predefined HKMetadataKeyTimeZone key.
Even Apple fails to add the time zone metadata to samples generated through their own Health app.
http://www.openmhealth.org/3-painful-lessons-learned-building-with-healthkit/
Abajo está mi código:
import HealthKit
let healthKitStore: HKHealthStore = HKHealthStore()
func getHealthDataValue_QuantityType(healthQuantityType : HKQuantityType?, strUnitType : String)
{
if let healthQuantityType = healthQuantityType {
if (HKHealthStore.isHealthDataAvailable()) {
let query = HKAnchoredObjectQuery(type: healthQuantityType, predicate: nil, anchor: nil, limit: Int(HKObjectQueryNoLimit)) { (query, newSamples, deletedSamples, newAnchor, error) -> Void in
guard let samples = newSamples as? [HKQuantitySample] else {
print("newSamples are nil, Error: \(error?.localizedDescription ?? "")\n, identifier: \(healthQuantityType.identifier)")
return
}
var healthKitData = [[String: Any]]()
for quantitySample in samples {
let quantity = quantitySample.quantity
let healthDataUnit : HKUnit
if (strUnitType.characters.count > 0 ) {
healthDataUnit = HKUnit(from: strUnitType)
} else {
healthDataUnit = HKUnit.count()
}
let tempActualhealthData = quantity.doubleValue(for: healthDataUnit)
var dicHealth = [String: Any]()
dicHealth["StartDate"] = quantitySample.startDate.epoch()
dicHealth["EndDate"] = quantitySample.endDate.epoch()
dicHealth["TimeZone"] = getTimeZoneString(sample: quantitySample)
dicHealth["Value"] = tempActualhealthData
dicHealth["Unit"] = strUnitType
dicHealth["Source"] = quantitySample.sourceRevision.source.name
dicHealth["WasUserEntered"] = quantitySample.metadata?["HKWasUserEntered"] as? Int
healthKitData.append(dicHealth)
}
print(healthKitData)
}
healthKitStore.execute(query)
}
}
}
extension Date {
func epoch(isMilliSeconds: Bool = false) -> UInt64 {
return UInt64(self.timeIntervalSince1970 * (isMilliSeconds ? 1000 : 1))
}
}
func getTimeZoneString(sample: HKSample? = nil, shouldReturnDefaultTimeZoneInExceptions: Bool = true) -> String? {
var timeZone: TimeZone?
print("sample?.metadata?[HKMetadataKeyTimeZone]: \(sample?.metadata?[HKMetadataKeyTimeZone])") // I have steps data recorded by my iPhone6s, not getting the timezone information for that health data.
if let metaDataTimeZoneValue = sample?.metadata?[HKMetadataKeyTimeZone] as? String {
timeZone = TimeZone(identifier: metaDataTimeZoneValue)
}
if shouldReturnDefaultTimeZoneInExceptions == true && timeZone == nil {
timeZone = TimeZone.current
}
var timeZoneString: String?
if let timeZone = timeZone {
let seconds = timeZone.secondsFromGMT()
let hours = seconds/3600
let minutes = abs(seconds/60) % 60
timeZoneString = String(format: "%+.2d:%.2d", hours, minutes)
}
return timeZoneString
}
var healthKitTypesToRead = Set<HKObjectType>()
if let stepCountObject = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount) {
healthKitTypesToRead.insert(stepCountObject)
}
healthKitStore.requestAuthorization(toShare: nil, read: healthKitTypesToRead) { (success, error) in
if error == nil {
getHealthDataValue_QuantityType(healthQuantityType: HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount), strUnitType: "count")
}
}