4

我正在使用 HealthKit 读取用户的健康数据。尝试从健康数据中获取时区信息,以确定健康活动发生在哪个确切时区。为此,我依赖 HealthKit 元数据中的“HKMetadataKeyTimeZone”键。但即使对于 Apple 的 Health 应用程序自动记录的健康数据,“HKMetadataKeyTimeZone”键的值也始终为零。在 Apple 的 Health 应用程序中手动输入的数据也存在同样的问题。

那么是否有任何其他键/方式可以为每个样本提供时区信息?

还是 Apple 的健康应用程序根本没有记录时区的健康数据信息?

还是 Apple 的健康应用程序正在记录时区的健康数据信息,而不是通过 HealthKit 框架将其提供给开发人员?

以下博客文章说,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/


下面是我的代码:

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")
  }
}
4

1 回答 1

2

没有不同的方法。如果您认为在 Health 应用程序中手动输入的数据应该有一个与之关联的时区,您应该向 Apple 提交错误。

于 2018-03-15T01:40:17.067 回答