📂
JackyChen的精神時光屋
  • About
  • iPlayground
    • iPlayground 2020
      • iPlayground submit 2020
    • iPlayground 2019
      • Untitled
      • iPlayground submit 2019
  • WWDC
    • 2020 WWDC
    • 2019 WWDC
    • 2018 WWDC
      • What's New in Testing
      • BusinessChat
    • 2016 WWDC
      • What's New in the Apple Push Notification Service
  • AR/VR
    • ARKit plugin at Unity
    • ARKit
    • AR/VR 實習作品分享
    • Google Blocks
  • CI/CD
    • Continous Integretion for Unity
    • 拯救地球大作戰-自動化設定注意事項
    • Provisioning Profile 自動化更新
    • Make ipa file with personal team of code sign
    • Xcode11 版號問題
  • Test
    • Cucumberish
    • XCUITest
    • Design Patterns in XCUITest
    • Unit Test
  • User Interface
    • IBDesignable 和 IBInspectable
    • iOS 使用貝塞爾曲線繪製路徑
    • UIStatusBarStyle
    • iOS Devices Specification
    • Vector Image
    • Launch Screen
    • Haptic Feedback
    • Good Works for Storyboard
    • Cell 展開收合效果
    • ScrollView
    • Swift lazy
    • Lottie
  • Foundation
    • Adding a Custom Font to Your App
    • WKWebView how to work with javascript
    • Global Central Dispatch
    • HealthKit
    • Error Handling
    • Debug with LLDB
    • Application Lifecycle
    • Swift Codable
    • Push Notifications
    • AVFoudation
  • Others
    • C語言指標概念
    • UnsafePointer(Swift)
    • iOS News Reference
    • Blender
    • Free Web Server
    • Firebase
    • Firebase migration
    • GraphQL
    • Ruby
    • zsh command line
    • visudo
  • Security
    • 課程:App資安規劃與實作
    • KeyChain
    • iOS反組譯程序
    • Arxan
  • Git
    • Git
    • xcodeproj 合併衝突
    • Pull Request
  • Machine Learning
    • CoreML
    • Vision
    • Turi Create
  • 待分類
    • ABI Stability and More
    • Mirror
    • Carthage
    • SwiftUI
    • MVVM
    • OpenSSL
    • USDZ Convert
    • Nexus repository and gitlfs
Powered by GitBook
On this page
  • 教學連結
  • Memo
  • Tell if data was user entered manually
  • 教學連結
  • Memo
  • Create Multiple predicate
  • 教學連結
  • 獲取統計數據
  • 教學連結
  • Memo

Was this helpful?

  1. Foundation

HealthKit

教學連結

  • How to Import and Export Health App Data using Swift

  • HealthKit Tutorial With Swift: Getting Started

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

教學連結

  • Ignore manual entries from Apple Health app as Data Source

    [NSPredicate predicateWithFormat:@"metadata.%K != YES", HKMetadataKeyWasUserEntered];
  • Detect if HealthKit activity has been entered manually

    • The bundle identifier of the entry if made manually will be com.apple.Health, which is the bundle identifier of the Health app. Notice the capital H. When you pull your data just ignore the data which has a bundle identifier of com.apple.Health.

      That way you will be only considering activities which are not manual

  • Using predicates to filter out sources when doing a query

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

教學連結

  • HealthKit: create a predicate for specific sources and date range

    • Use NSCompoundPredicate

  • NSCompoundPredicate

  • 程式範例

    //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])

獲取統計數據

教學連結

  • HKStatisticsCollectionQuery

  • Get total step count for every date in HealthKit

Memo

  • 心率單位

    HKUnit(from: "count/min")
    or
    HKUnit.count().unitDivided(by: HKUnit.minute())
PreviousGlobal Central DispatchNextError Handling

Last updated 5 years ago

Was this helpful?