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 {
                // 写入数据失败
            }
        }
    }

四、运行获取权限页面

相关推荐
专业开发者6 小时前
调试 iOS 蓝牙应用的新方法
物联网·macos·ios·cocoa
tangbin58308511 小时前
iOS Swift 可选值(Optional)详解
前端·ios
卷心菜加农炮1 天前
基于Python的FastAPI后端开发框架如何使用PyInstaller 进行打包与部署
ios
北极象1 天前
千问大模型接入示例
ios·iphone·qwen
ipad协议开发1 天前
企业微信 iPad 协议应用机器人开发
ios·企业微信·ipad
QuantumLeap丶2 天前
《Flutter全栈开发实战指南:从零到高级》- 26 -持续集成与部署
android·flutter·ios
2501_915918412 天前
TCP 抓包分析在复杂网络问题中的作用,从连接和数据流层面理解系统异常行为
网络·网络协议·tcp/ip·ios·小程序·uni-app·iphone
二流小码农2 天前
鸿蒙开发:个人开发者如何使用华为账号登录
android·ios·harmonyos
wvy2 天前
Xcode 26还没有适配SceneDelegate的app建议尽早适配
ios
游戏开发爱好者82 天前
苹果 App 上架流程,结合 Xcode、CI 等常见工具
macos·ios·ci/cd·小程序·uni-app·iphone·xcode