HealthKit

教學連結

Memo

  • 三大重點:取得資料授權、讀、寫

    • How to request permission and access HealthKit data

    • How to read HealthKit data

    • How to write data to HealthKit’s central repository

  • 授權

//3. Prepare a list of types you want HealthKit to read and write
let healthKitTypesToWrite: Set<HKSampleType> = [bodyMassIndex,
                                                activeEnergy,
                                                HKObjectType.workoutType()]

let healthKitTypesToRead: Set<HKObjectType> = [dateOfBirth,
                                               bloodType,
                                               biologicalSex,
                                               bodyMassIndex,
                                               height,
                                               bodyMass,
                                               HKObjectType.workoutType()]
//4. Request Authorization
HKHealthStore().requestAuthorization(toShare: healthKitTypesToWrite,
                                     read: healthKitTypesToRead) { (success, error) in
  completion(success, error)
}
class func getMostRecentSample(for sampleType: HKSampleType,
                               completion: @escaping (HKQuantitySample?, Error?) -> Swift.Void) {

//1. Use HKQuery to load the most recent samples.  
let mostRecentPredicate = HKQuery.predicateForSamples(withStart: Date.distantPast,
                                                      end: Date(),
                                                      options: .strictEndDate)

let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate,
                                      ascending: false)

let limit = 1

let sampleQuery = HKSampleQuery(sampleType: sampleType,
                                predicate: mostRecentPredicate,
                                limit: limit,
                                sortDescriptors: [sortDescriptor]) { (query, samples, error) in

    //2. Always dispatch to the main thread when complete.
    DispatchQueue.main.async {

      guard let samples = samples,
            let mostRecentSample = samples.first as? HKQuantitySample else {

            completion(nil, error)
            return
      }

      completion(mostRecentSample, nil)
    }
  }

HKHealthStore().execute(sampleQuery)
}
class func saveBodyMassIndexSample(bodyMassIndex: Double, date: Date) {

  //1.  Make sure the body mass type exists  
  guard let bodyMassIndexType = HKQuantityType.quantityType(forIdentifier: .bodyMassIndex) else {
    fatalError("Body Mass Index Type is no longer available in HealthKit")
  }

  //2.  Use the Count HKUnit to create a body mass quantity
  let bodyMassQuantity = HKQuantity(unit: HKUnit.count(),
                                    doubleValue: bodyMassIndex)

  let bodyMassIndexSample = HKQuantitySample(type: bodyMassIndexType,
                                             quantity: bodyMassQuantity,
                                             start: date,
                                             end: date)

  //3.  Save the same to HealthKit
  HKHealthStore().save(bodyMassIndexSample) { (success, error) in

    if let error = error {
      print("Error Saving BMI Sample: \(error.localizedDescription)")
    } else {
      print("Successfully saved BMI Sample")
    }
  }
}

Tell if data was user entered manually

教學連結

Memo

  • 非手動輸入

(lldb) po samples[1].source.bundleIdentifier
"com.apple.health.6AE18D38-5413-4679-BDBA-7FBD1DA9A45C"

(lldb) po samples[1].source.name
"電商科的iPhoneX"

(lldb) po samples[1].metadata
nil
  • 手動輸入

(lldb) po samples[2].source.bundleIdentifier
"com.apple.Health"

(lldb) po samples[2].source.name
"健康"

(lldb) po samples[2].metadata
▿ Optional<Dictionary<String, Any>>
  ▿ some : 1 element
    ▿ 0 : 2 elements
      - key : "HKWasUserEntered"
      - value : 1

Create Multiple predicate

教學連結

  • 程式範例

    //1. Get all workouts with the "Other" activity type.
    let workoutPredicate = HKQuery.predicateForWorkouts(with: .other)
    
    //2. Get all workouts that only came from this app.
    let sourcePredicate = HKQuery.predicateForObjects(from: HKSource.default())
    
    //3. Combine the predicates into a single predicate.
    let compound = NSCompoundPredicate(andPredicateWithSubpredicates: [workoutPredicate,
                                                                       sourcePredicate])

獲取統計數據

教學連結

Memo

  • 心率單位

    HKUnit(from: "count/min")
    or
    HKUnit.count().unitDivided(by: HKUnit.minute())

Last updated