Swift: HealthKit에 체온 데이터를 입력합니다. 가능한 한 공식 문서 만보십시오.

13704 단어 SwiftHealthKit
우선은 공식 문서를 제대로 읽는 인간이 되려고 생각했고, Apple 공식 문서만을 바탕으로 HealthKit에 액세스를 시도했습니다.

환경


  • XCode Version 13.0
  • iOS target 14.0

  • 참고(공식)


  • 전설
  • htps : //로 ゔぇぺぺr. 아 ぇ. 코 m / 도쿠 멘 타치 온 / 헤아 lth t / 아보 t_ 테 _ 헤아 lth t_f 라메 rk

  • XCode에서 HealthKit 사용
  • htps : //에서 ゔぇぺぺr. 아 ぇ. 코 m / 도쿠 멘 타치 온 / 헤아 lth 키 t / 세치 친 g_u p_ 헤아 lth 키 t

  • 프라이버시 데이터에 액세스하기 위한 프로젝트 설정
  • htps : //로 ゔぇぺぺr. 아 ぇ. 코 m / 도쿠 멘 타치 온 / 헤아 lth 키 t / p 로테 c 짱 g_ 우세 r_p 리 ゔ

  • Swift에서 건강 관리 데이터에 액세스
  • htps : //에서 ゔぇぺぺr. 아 ぇ. 코 m / 도쿠 멘 타치 온 / 헤아 lth t / 아우 테 조 린 g_ 아세스 s_와 _ 헤아 lth_


  • 프로젝트 설정



    HealthKit 활성화 (프로젝트 설정의 "Signing & Capabilities"에 HealthKit 추가



    액세스 요청에 대한 메시지 정의



    이번에는 체온 데이터를 입력하기 때문에 Privacy - Health Update Usage Description앱이 읽는 경우 Privacy - Health Share Usage Description가 필요합니다.

    참고 : Protecting User Privacy (developer.apple.com)

    이러한 Description은 13자 이상 필요한 것 같습니다. 이것에 관해서는 조사력이 부족해, StackOverflow의 신세가 되었습니다.

    https://stackoverflow.com/questions/37863093/exception-nsinvalidargumentexception-nshealthupdateusagedescritption

    코드



    이번에는 한 클래스 내에서 HealthKit에 대한 참조를 완료합니다.

    setup()


    HKHealthStore 는 문서에 따르면, 어둠 속에서 생성하지 않고 계속 유지하는 것이 좋은 것 같습니다.

    You need only a single HealthKit store per app. These are long-lived objects; you create the store once, and keep a reference for later use.

    Setting Up HealthKit (developer.apple.com)

    에러 체크로 호출측의 처리를 바꾸는 것도 고려해, setup() 메소드로 Store의 생성을 실시합니다. (에러 체크가 불필요하면 init()내에서 생성하고 있었습니다)

    postBodyTemperature()



    이하의 순서로 처리를 실시합니다
  • 체온 데이터에 대한 사용 권한 취득
  • 사용 권한 상태 확인
  • 체온 데이터 저장

  • 완성된 클래스


    import Foundation
    import HealthKit
    
    enum BodyTemperatureUnit{
        /// 摂氏
        case degreeCelsius
        /// 華氏
        case degreeFahrenheit
    }
    class HealthCareRepository{
        let allTypes = Set([HKObjectType.quantityType(forIdentifier: .bodyTemperature)!])
        /// HKHealthStoreはアプリケーションあたり1インスタンス。1回生成したらそれを使い続ける必要あり
        var store:HKHealthStore? = nil
    
        func setup() -> Bool{
            /// ipadではヘルスケア使えない
            /// https://developer.apple.com/documentation/healthkit/setting_up_healthkit
            /// Ensure HealthKit’s Availability
            if (HKHealthStore.isHealthDataAvailable() == false){
                // ヘルスデータが無効状態
                return false
            }
    
            /// ヘルスケア機能があり、有効である場合生成する
            self.store = HKHealthStore()
            return true
        }
    
        func postBodyTemperature(_ value:Double, unit:BodyTemperatureUnit, completion:@escaping (Bool, Error?) -> Void) -> Void{
    
            /// https://developer.apple.com/documentation/healthkit/authorizing_access_to_health_data
            /// Request Permission from the User
            /// toShare: Write要求
            /// read: Read要求
            self.store!.requestAuthorization(toShare: allTypes, read: nil){ (success, error) in
                if !success{
                    completion(success, error)
                    return
                }
    
                /// https://developer.apple.com/documentation/healthkit/authorizing_access_to_health_data
                /// Check for Authorization Before Saving Data
                let status = self.store!.authorizationStatus(for: .quantityType(forIdentifier: .bodyTemperature)!)
                switch status{
                case .notDetermined:
                    // "If you have not yet requested permission"
                    // ここに入ることはないはず
                    print("Not determined")
                    completion(false, HKError(HKError.errorAuthorizationNotDetermined))
                    return
                case .sharingDenied:// If the user has denied permission
                    // ユーザーが許可しなかった場合
                    print("Sharing Denied")
                    completion(false, HKError(HKError.errorAuthorizationDenied))
                    break
                case .sharingAuthorized:
                    // ユーザーが許可した場合
                    print("Sharing Authorized")
                    break
                @unknown default:
                    print("Unknown status.")
                    break
                }
    
                // Datetime
                let now = Date()
                // 摂氏 or 華氏
                let hkUnit:HKUnit
                switch unit {
                case .degreeCelsius:
                    hkUnit = .degreeCelsius()
                case .degreeFahrenheit:
                    hkUnit = .degreeFahrenheit()
                }
    
                let quantity = HKQuantity(unit: hkUnit, doubleValue: value)
                let obj = HKQuantitySample(type: .quantityType(forIdentifier: .bodyTemperature)!, quantity: quantity, start: now, end: now)
                self.store!.save(obj, withCompletion: completion)
            }
        }
    }
    

    결과



    적당한 UI 만들어 위의 클래스를 시도한 결과, 시뮬레이터상입니다만 무사히 체온 데이터를 헬스케어에 등록할 수 있었습니다. 대부분의 것은 공식 Document에 써 있는 것도 실감할 수 있었습니다. 다음 번은 UI 예정입니다.

    좋은 웹페이지 즐겨찾기