
WWDC2020 : Getting started with HealthKit
WWDC2020 : Synchronize health data with HealthKit
2020 : Beyond counting steps
HealthKit Officail Document
HealthKit Article : Setting Up HealthKit
override func viewDidLoad() {
        super.viewDidLoad()
 	if HKHealthStore.isHealthDataAvailable() {
    
 	}
 }
override func viewDidLoad() {
        super.viewDidLoad()
        if HKHealthStore.isHealthDataAvailable() {
            
            let healthStore = HKHealthStore()
            let readDataTypes : Set = [HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!,
                                       HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)!
            ]
            
            healthStore.requestAuthorization(toShare: nil, read: readDataTypes) { (success, error) in
                if !success {
                    // Handle the error here.
                } else {
                    // Enter your logic here.
                }
            }
        }
                




    let sampleType = HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)
        let today = Date()
        let startDate = Calendar.current.date(byAdding: .day, value: -7, to: today)
        let predicate = HKQuery.predicateForSamples(withStart: startDate, end: today, options: HKQueryOptions.strictEndDate)
        let query = HKSampleQuery.init(sampleType: sampleType!,
                                       predicate: predicate,
                                       limit: HKObjectQueryNoLimit,
                                       sortDescriptors: [NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)])
   /// Mark: -  한달의 걸음 수와 걸은 시간을 날짜별로 가져오는 함수
    func getOneMonthStepCountAndWalkingTimePerDay() {
        var realmWalking : [Walking] = []
        let sampleType = HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)
        let today = Date()
        let startDate = Calendar.current.date(byAdding: .day, value: -7, to: today)
        let predicate = HKQuery.predicateForSamples(withStart: startDate, end: today, options: HKQueryOptions.strictEndDate)
        let query = HKSampleQuery.init(sampleType: sampleType!,
                                       predicate: predicate,
                                       limit: HKObjectQueryNoLimit,
                                       sortDescriptors: [NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)]) { (query, results, error) in
            
            var dateOneIndexBeforeBuffer : Date? = nil
            var walkingDataBuffer : Walking = Walking()
            var stepCountBuffer : Int = 0
            var walkingSecondBuffer : Double = 0.0
            
            print("------------------------------------------------------------------------------------")
            results?.compactMap{
                $0
            }.forEach{ stepCountInfo in
                
                
                // Apple Watch와 중복 계산을 막아준다.
                if !stepCountInfo.description.contains("Watch"){
                    // Day 구분을 위해 StartDate에서 시간을 지워준다.
                    let startDate = convertStringToDate(dateString: (convertDateToString(date: stepCountInfo.startDate, format: "yyMMdd")), format: "yyMMdd")
                    
                    // 하나 전 인덱스와 비교해준다.
                    if dateOneIndexBeforeBuffer != nil {
                        // 시작일이 전 인덱스의 시작일과 다르다면 날짜가 바뀐 것.
                        
                            print("RESULT :: \(stepCountInfo.description)")
                        if startDate < dateOneIndexBeforeBuffer! {
                            
                            // 날짜가 바뀌면 해당 날짜와, 해당 일의 걸음 수 걸음 시간 각각의 총 합을 객체에 넣어준다.
                            // 인덱스 (인덱스는 날짜로 선언한다 가변적인 데이터에 대응하기 위해 같은 날짜의 데이터는 Realm에서 Update & Insert를 진행한다.
                            walkingDataBuffer.id = dateOneIndexBeforeBuffer!.millisecondsSince1970
                            print("*** WALKING DATE PER CELL  :: \(walkingDataBuffer.id)")
                            
                            // 걸음 수
                            walkingDataBuffer.walkingCount = stepCountBuffer
                            print("*** TOTAL WALKING COUNT PER CELL  :: \(walkingDataBuffer.walkingCount)")
                            
                            // 운동 시간
                            walkingDataBuffer.walkingSecond = Int(round(walkingSecondBuffer))
                            print("*** TOTAL WALKING TIME PER CELL  :: \(walkingDataBuffer.walkingSecond)")
                            print("------------------------------------------------------------------------------------")
                            
                            // 리셋 버퍼 벨류
                            walkingSecondBuffer = 0.0
                            stepCountBuffer = 0
                            
                            // DB에 들어갈 객체에 넣어준다.
                            realmWalking.append(walkingDataBuffer)
                        }
                        
                    }
                    
                    // 걸은 시간
                    // 운동을 마친 시간과 시작 시간의 timeIntervalSinceReferenceDate 값을 빼주면 운동을 한 시간이 계산된다.
                    let walkingSecond = stepCountInfo.endDate.timeIntervalSince1970 - stepCountInfo.startDate.timeIntervalSince1970
                    
                    // 걸은 시간을 더해준다.
                    walkingSecondBuffer += walkingSecond
                    
                    // 걸음 수
                    let stepCount = Int(stepCountInfo.description.components(separatedBy: " count")[0])
                    
                    // 걸음 수를 더해준다.
                    stepCountBuffer += stepCount ?? 0
                    
                    // 다음 인덱스에서 확인할 수 있게 Date를 dateOneIndexBeforeBuffer 에 저장해준다.
                    dateOneIndexBeforeBuffer = startDate
                }
                
            }
            
        }
        healthStore.execute(query)
    }

 if !stepCountInfo.description.contains("Watch")
   ///  설정한 기간동안의 걸음 수를 조회할 수 있는 쿼리.
    /// - Parameter completion: cumulative parameter sum
    func getTodaysSteps(completion: @escaping (Double) -> Void) {
        let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
        let now = Date()
        let startDate = Calendar.current.date(byAdding: .day, value: -6, to: Date())!
        let predicate = HKQuery.predicateForSamples(
            withStart: startDate,
            end: now,
            options: .strictStartDate
        )
        let query = HKStatisticsQuery(
            quantityType: stepsQuantityType,
            quantitySamplePredicate: predicate,
            options: .separateBySource
        ) { _, result, _ in
            guard let result = result, let sum = result.sumQuantity() else {
                print("Step Zero")
                completion(0.0)
                return
            }
            print("result check \(result)")
            completion(sum.doubleValue(for: HKUnit.count()))
        }
        healthStore.execute(query)
    }
// 날짜별 스탭카운트 얻기
    func getStepCountPerDay(finishCompletion: @escaping () -> Void){
        guard let sampleType = HKObjectType.quantityType(forIdentifier: .stepCount)
            else {
                return
        }
        let calendar = Calendar.current
        var dateComponents = DateComponents()
        dateComponents.day = 1
        var anchorComponents = calendar.dateComponents([.day, .month, .year], from: Date())
        anchorComponents.hour = 0
        let anchorDate = calendar.date(from: anchorComponents)
        let stepsCumulativeQuery = HKStatisticsCollectionQuery(quantityType: sampleType, quantitySamplePredicate: nil, options: .cumulativeSum, anchorDate: anchorDate!, intervalComponents: dateComponents
        )
        // Set the results handler
        stepsCumulativeQuery.initialResultsHandler = {query, results, error in
            let endDate = Date()
            let startDate = calendar.date(byAdding: .day, value: -30, to: endDate, wrappingComponents: false)
            if let myResults = results{
                myResults.enumerateStatistics(from: startDate!, to: endDate as Date) { [self] statistics, stop in
                    if let quantity = statistics.sumQuantity(){
                        let date = statistics.startDate
                        let steps = quantity.doubleValue(for: HKUnit.count())
                        print("START DATE :: \(statistics.startDate)")
                        print("STEP COUNT :: \(steps)")
                        print("-------------------------------------------------------------")
                    }
                }
            } else {
                print("STEP COUNT DATA NIL")
            }
        }
        HKHealthStore().execute(stepsCumulativeQuery)
        finishCompletion()
    }

 if let quantity = statistics.sumQuantity()

