XZ_Swift 之HealthKit 获取手机计步统计

 

目录

1、配置工程

2、设置Capabilities

3、设置 Info.plist

4、错误解决

5、代码编写

6、demo下载


1、配置工程

注意:Team这个地方必须是企业的或者是公司的,不能是Personal Team。如下图

2、设置Capabilities

设置完了之后,左侧会出现 XZHealthDemo.entitlements。如下图:

3、设置 Info.plist

注意:描述语句只能写 "some string value stating the reason",其他的都会崩溃。

Privacy - Health Share Usage Description  // 读取权限
some string value stating the reason
Privacy - Health Update Usage Description // 写入权限
some string value stating the reason

或者
<key>NSHealthShareUsageDescription</key>
<string>some string value stating the reason</string>
<key>NSHealthUpdateUsageDescription</key>
<string>some string value stating the reason</string>

4、错误解决

出现错误:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSHealthUpdateUsageDescription must be set in the app's Info.plist in order to request write authorization for the following types: HKQuantityTypeIdentifierStepCount'

解决 同 3 设置Info.plist

5、代码编写

1>判断设备是否支持 HealthKit 框架

func isHealthDataAvailable() -> Bool

2>判断是否支持健康记录,iOS 12.0 以上系统

func supportsHealthRecords() -> Bool

3>某一种健康类型的支持状态

func authorizationStatus(for type: HKObjectType) -> HKAuthorizationStatus

HKAuthorizationStatus 有3种结果:
notDetermined // 不确定
sharingDenied  // 不允许
sharingAuthorized // 允许

4>请求读写权限:在用户读取和写入数据之前,需要请求是否有权限。

要自定义显示在授权表上的消息,请在您的应用程序中设置以下键 Info.plist 中:

设置NSHealthShareUsageDescription键,自定义用于读取数据的消息。

设置NSHealthUpdateUsageDescription键,自定义用于编写数据的消息。

func requestAuthorization(toShare typesToShare: Set<HKSampleType>?, read typesToRead: Set<HKObjectType>?, completion: @escaping (Bool, Error?) -> Void)

5>是否有读写的权限,iOS 12.0 系统以上

func getRequestStatusForAuthorization(toShare typesToShare: Set<HKSampleType>, read typesToRead: Set<HKObjectType>, completion: @escaping (HKAuthorizationRequestStatus, Error?) -> Void)

6>保存某个数据

func save(_ object: HKObject, withCompletion completion: @escaping (Bool, Error?) -> Void)

7>保存多个数据

func save(_ objects: [HKObject], withCompletion completion: @escaping (Bool, Error?) -> Void)

8>执行查询方法

func execute(_ query: HKQuery)

9>停止查询

func stop(_ query: HKQuery)

导入HealthKit框架

import HealthKit

授权读写步数

    /// 授权 步数 读写
    func authorizeStepCount(completed: @escaping ((_ isSuccess: Bool)->Void)) {
        
        if HKHealthStore.isHealthDataAvailable() {
            let writeTypes = stepCountToWrite()
            let readTypes = stepCountToRead()
            
            healthStore.requestAuthorization(toShare: writeTypes, read: readTypes) { (success, error) in
                
                completed(success)
                print("----步数读写:", success)
            }
        }
    }


    /// 步数 读 权限
    func stepCountToRead() -> Set<HKQuantityType>? {
        let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)
        
        return Set(arrayLiteral: stepType!)
    }
    
    /// 步数 写 权限
    func stepCountToWrite() -> Set<HKQuantityType>? {
        let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)
        
        return Set(arrayLiteral: stepType!)
    }

授权 读写 健康数据

 func authorizeHealthKit(completed: @escaping ((_ isSuccess: Bool)->Void)) {
        
        let version = UIDevice.current.systemVersion.floatValue()
        
        if version >= 8.0 {
            if !HKHealthStore.isHealthDataAvailable() {
                
//                let error = NSError(domain: "com.xz.healthkit", code: 2, userInfo: [NSLocalizedDescriptionKey:"HealthKit is not available in th is Device"])
                
                completed(false)
            }else { // 可用
                // 需要读写的数据类型
                let writeDataTypes = dateTypeToWrite()
                let readDataTypes = dateTypeToRead()
                
                // 注册需要读写的数据类型,也可以在'健康'中重新修改
                healthStore.requestAuthorization(toShare: writeDataTypes, read: readDataTypes, completion: { (isSuccess, error) in
                    
                    print("错误:", error)
                    print("权限结果:", isSuccess)
                    
                    completed(isSuccess)
                })
            }
        }else {
            print("iOS 系统低于8.0")
            completed(false)
        }
    }

    // 读取 Health 数据
    func dateTypeToRead() -> Set<HKQuantityType>? {
        // 身高
        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 stepCountType = HKQuantityType.quantityType(forIdentifier: .stepCount)
        // 距离
        let distanceType = HKObjectType.quantityType(forIdentifier: .distanceWalkingRunning)
        // 活动能量
        let activeEnergyType = HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)
        
        return Set(arrayLiteral: heightType, temperatureType, birthdayType, sexType, weightType, stepCountType, distanceType, activeEnergyType) as? Set<HKQuantityType>
    }
    
    // 写 Health 数据
    func dateTypeToWrite() -> Set<HKQuantityType>? {
        // 身高
        let heightType = HKObjectType.quantityType(forIdentifier: .height)
        // 体重
        let weightType = HKObjectType.quantityType(forIdentifier: .bodyMass)
        // 体温
        let temperatureType = HKObjectType.quantityType(forIdentifier: .bodyTemperature)
        // 活动能量
        let activeEnergyType = HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)
        
        return Set(arrayLiteral: heightType, temperatureType, weightType, activeEnergyType) as? Set<HKQuantityType>
    }

修改数据

    func recordStepData(step: Int, completed: @escaping ((_ success: Bool)->Void)) {
        
        let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)
        
        if HKHealthStore.isHealthDataAvailable() {
            let stepQuantity = HKQuantity(unit: HKUnit.count(), doubleValue: Double(step))
            let stepSample = HKQuantitySample(type: stepType!, quantity: stepQuantity, start: Date(), end: Date())
            
            healthStore.save(stepSample) { (isSuccess, error) in
                
                print("修改结果:", isSuccess)
                completed(isSuccess)
            }
        }else {
            print("写入不允许")
        }
    }

获取步数数据

    /// 获取步数
    func getStepCount(completion: @escaping ((_ value: Int)->Void)) {
        // 步数
        let stepType = HKObjectType.quantityType(forIdentifier: .stepCount)
        
        let timeSortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
        
        let query = HKSampleQuery(sampleType: stepType!, predicate: predicateForSampelsToday(), limit: HKObjectQueryNoLimit, sortDescriptors: [timeSortDescriptor]) { (query, results, error) in
            
            if error != nil {
                
                completion(0)
            }else {
                var totalStep = 0
                
                if let results = results {
                    for quantitySample in results {
                        
                        let quantitySam = quantitySample as! HKQuantitySample
                        
                        let quantity = quantitySam.quantity
                        let heightUnit = HKUnit.count()
                        let usersHeight = quantity.doubleValue(for: heightUnit)
                        totalStep += Int(usersHeight)
                    }
                    
                    print("当天行走步数 =", totalStep)
                    completion(totalStep)
                }
            }
        }
        
        // 执行查询
        healthStore.execute(query)
    }

6、demo下载

下一篇:《XZ_iOS 之 使用 CoreMotion 获取步数》

猜你喜欢

转载自blog.csdn.net/understand_XZ/article/details/89404802