iOS HealthKit 介绍

文章目录

  • 一、简介
  • 二、权限配置
    • [1. 在开发者账号中勾选HealthKit](#1. 在开发者账号中勾选HealthKit)
    • [2. 在targets的capabilities中添加HealthKit。](#2. 在targets的capabilities中添加HealthKit。)
    • [3. infoPlist需要配置权限](#3. infoPlist需要配置权限)
  • 三、创建健康数据管理类
    • [1. 引入头文件](#1. 引入头文件)
    • [2. 健康数据读写权限](#2. 健康数据读写权限)
    • [3. 检查权限](#3. 检查权限)
    • [4. 读取步数数据](#4. 读取步数数据)
    • [5. 写入健康数据](#5. 写入健康数据)
  • 四、运行获取权限页面

一、简介

HealthKit是一款用于搜集和办理医疗和健康相关数据的开发工具包,它为开发者供给了拜访用户健康数据的API和框架,并使得这些数据能够与iOS设备上的其他应用程序相互共享。

HealthKit允许应用程序搜集和办理各种类型的健康数据,包含身体丈量数据(如体重、身高和心率)、健身数据(如步数和距离)、饮食数据、睡觉数据和心理健康数据等。这些数据能够从多个来历搜集,如从硬件设备(如智能手表、智能手机和健身跟踪器)中获取,或由用户手动输入。

二、权限配置

1. 在开发者账号中勾选HealthKit

2. 在targets的capabilities中添加HealthKit。

3. infoPlist需要配置权限

Privacy - Health Share Usage Description

需要您的同意,才能访问健康更新,给您带来更好的服务
Privacy - Health Update Usage Description

需要您的同意,才能分享健康数据,给您带来更好的服务

注意:iOS13 这里描述太粗糙,会导致程序崩溃。

三、创建健康数据管理类

1. 引入头文件

import HealthKit

2. 健康数据读写权限

// 写权限
    private func dataTypesToWrite() -> Set<HKSampleType> {
        // 步数
        let stepCountType = HKObjectType.quantityType(forIdentifier: .stepCount)
        // 身高
        let heightType = HKObjectType.quantityType(forIdentifier: .height)
        // 体重
        let weightType = HKObjectType.quantityType(forIdentifier: .bodyMass)
        // 活动能量
        let activeEnergyType = HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)
        // 体温
        let temperatureType = HKObjectType.quantityType(forIdentifier: .bodyTemperature)
        // 睡眠分析
        let sleepAnalysisType = HKObjectType.categoryType(forIdentifier: .sleepAnalysis)
        
        let setTypes = Set([stepCountType, heightType, weightType, activeEnergyType, temperatureType, sleepAnalysisType].compactMap { $0 })
        return setTypes
    }
    
    // 读权限
    private func dataTypesToRead() -> Set<HKObjectType> {
        // 步数
        let stepCountType = HKObjectType.quantityType(forIdentifier: .stepCount)
        // 身高
        let heightType = HKObjectType.quantityType(forIdentifier: .height)
        // 体重
        let weightType = HKObjectType.quantityType(forIdentifier: .bodyMass)
        // 体温
        let temperatureType = HKObjectType.quantityType(forIdentifier: .bodyTemperature)
        // 出生日期
        let birthdayType = HKObjectType.characteristicType(forIdentifier: .dateOfBirth)
        // 性别
        let sexType = HKObjectType.characteristicType(forIdentifier: .biologicalSex)
        // 步数+跑步距离
        let distance = HKObjectType.quantityType(forIdentifier: .distanceWalkingRunning)
        // 活动能量
        let activeEnergyType = HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)
        // 睡眠分析
        let sleepAnalysisType = HKObjectType.categoryType(forIdentifier: .sleepAnalysis)
        
        let setTypes = Set([stepCountType, heightType, weightType, activeEnergyType, birthdayType, sexType, distance, temperatureType, sleepAnalysisType].compactMap { $0 })
        return setTypes
    }

3. 检查权限

/// 检查是否支持获取健康数据
    public func authorizeHealthKit(_ compltion: ((_ success: Bool, _ error: Error?) -> Void)?) {
        guard HKHealthStore.isHealthDataAvailable() == true else {
            let error = NSError(domain: "不支持健康数据", code: 2, userInfo: [NSLocalizedDescriptionKey: "HealthKit is not available in th is Device"])
            if let compltion = compltion {
                compltion(false, error)
            }
            return
        }
        let writeDataTypes = dataTypesToWrite()
        let readDataTypes = dataTypesToRead()
        healthStore.requestAuthorization(toShare: writeDataTypes, read: readDataTypes) { success, error in
            if let compltion = compltion {
                compltion(success, error)
            }
        }
    }

4. 读取步数数据

/// 获取步数
    public func getStepCount(_ completion: @escaping ((_ stepValue: String?, _ error: Error?) -> Void)) {
        // 要检索的数据类型。
        guard let stepType = HKObjectType.quantityType(forIdentifier: .stepCount) else {
            let error = NSError(domain: "不支持健康数据", code: 2, userInfo: [NSLocalizedDescriptionKey: "HealthKit is not available in th is Device"])
            completion(nil, error)
            return
        }
        
        // NSSortDescriptors用来告诉healthStore怎么样将结果排序。
        let start = NSSortDescriptor.init(key: HKSampleSortIdentifierStartDate, ascending: false)
        let end = NSSortDescriptor.init(key: HKSampleSortIdentifierEndDate, ascending: false)
        /*
         @param         sampleType      要检索的数据类型。
         @param         predicate       数据应该匹配的基准。
         @param         limit           返回的最大数据条数
         @param         sortDescriptors 数据的排序描述
         @param         resultsHandler  结束后返回结果
         */
        let query = HKSampleQuery.init(sampleType: stepType, predicate: HealthKitManager.getStepPredicateForSample(), limit: HKObjectQueryNoLimit, sortDescriptors: [start, end]) { _, results, error in
            guard let results = results else {
                completion(nil, error)
                return
            }
            print("resultCount = \(results.count) result = \(results)")
            // 把结果装换成字符串类型
            var totleSteps = 0
            results.forEach({ quantitySample in
                guard let quantitySample = quantitySample as? HKQuantitySample else {
                    return
                }
                let quantity = quantitySample.quantity
                let heightUnit = HKUnit.count()
                let usersHeight = quantity.doubleValue(for: heightUnit)
                totleSteps += Int(usersHeight)
            })
            print("最新步数:\(totleSteps)")
            completion("\(totleSteps)", error)
        }
        healthStore.execute(query)
    }

5. 写入健康数据

/// 写入数据
    public func writeStep() {
        let steps = HKObjectType.quantityType(forIdentifier: .stepCount)!
        let quantity = HKQuantity(unit: HKUnit.count(), doubleValue: 1000)
        let now = Date()
        let start = now.addingTimeInterval(-3600 * 24)
        let end = now
        let sample = HKQuantitySample(type: steps, quantity: quantity, start: start, end: end)
        let healthStore = HKHealthStore()
        healthStore.save(sample) { (success, _) in
            if success {
                // 数据已写入 HealthKit
            } else {
                // 写入数据失败
            }
        }
    }

四、运行获取权限页面

相关推荐
陈皮话梅糖@4 小时前
iOS 集成ffmpeg
ios·ffmpeg
幽夜落雨5 小时前
ios老版本应用安装方法
ios
胖虎113 小时前
实现 iOS 自定义高斯模糊文字效果的 UILabel(文末有Demo)
ios·高斯模糊文字·模糊文字
_可乐无糖2 天前
Appium 检查安装的驱动
android·ui·ios·appium·自动化
胖虎12 天前
iOS 网络请求: Alamofire 结合 ObjectMapper 实现自动解析
ios·alamofire·objectmapper·网络请求自动解析·数据自动解析模型
开发者如是说3 天前
破茧英语路:我的经验与自研软件
ios·创业·推广
假装自己很用心3 天前
iOS 内购接入StoreKit2 及低与iOS 15 版本StoreKit 1 兼容方案实现
ios·swift·storekit·storekit2
iOS阿玮3 天前
“小红书”海外版正式更名“ rednote”,突然爆红的背后带给开发者哪些思考?
ios·app·apple
刘小哈哈哈3 天前
iOS UIScrollView的一个特性
macos·ios·cocoa
忆江南的博客4 天前
iOS 性能优化:实战案例分享
ios