计步器

如今不少应用中加入了健康这个模块, 像微信一样展示每天运动步数或其他数据, 那么我们如何获取这些数据呢?

新建一个manager类, 代码及注释如下:

import UIKit
import HealthKit

typealias completion = (_ success: Bool, _ error: Error?) -> Void
typealias totalClosure = (_ value: Double, _ error: Error?) -> Void
class BBSHealthKitManager: NSObject {

    fileprivate var healthStore: HKHealthStore?
    
    static let shareInstance = BBSHealthKitManager()
    
    public func authorizeHealthKit(completion: @escaping completion)
    {
        if #available(iOS 8.0, *) {
        
            if HKHealthStore.isHealthDataAvailable() {
                
                self.healthStore = HKHealthStore.init()
                // 组装需要读写的数据类型
                let write = dataTypesWrite()
                let read = dataTypeRead()
                
                // 注册需要读写的数据类型  也可以在健康app中重新修改
                self.healthStore?.requestAuthorization(toShare: write, read: read, completion: { (success, error) in
                    
                    completion(success, error)
                    
                })
                
            }else{
                
                let error : NSError = NSError.init(domain: "com.raywenderlich.tutorials.healthkit", code: 2, userInfo: [NSLocalizedDescriptionKey : "HealthKit is not available in th is Device"])
                
                completion(false,error)
                
                return
                
            }
        
        } else {
            
            let error : NSError = NSError.init(domain: "com.sdqt.healthError", code: 0, userInfo: [NSLocalizedDescriptionKey : "iOS 系统低于8.0"])
            
            completion(false,error)
            
            
        }
    }
    
    /**
     - brief  写权限
     - return 集合
     */
    fileprivate func dataTypesWrite() -> Set<HKQuantityType>
    {
        return Set()
    }
    
    /**
     - brief  读权限
     - return 集合
     */
    fileprivate func dataTypeRead() -> Set<HKQuantityType>
    {
        let stepCount = HKQuantityType.quantityType(forIdentifier: .stepCount)
        return Set.init(arrayLiteral: stepCount!)
    }
    
    // 读取步数
    public func getStepCount(totalClosure: @escaping totalClosure)
    {
        let stepCount = HKQuantityType.quantityType(forIdentifier: .stepCount)
        
        let timeSortDescriptor = NSSortDescriptor.init(key:HKSampleSortIdentifierEndDate, ascending: false)
        
        let query = HKSampleQuery.init(sampleType:stepCount!, predicate: predicateForSamplesToday(), limit: 0, sortDescriptors: [timeSortDescriptor]) { (query, results, error) in
            
            if let err: Error = error {
                totalClosure(0, err)
            }else{
                
                var  totalSteps:Double = 0.0;
                
                for i in 0 ..< (results?.count)! {
                    
                    let quantitySample =  results?[i] as! HKQuantitySample
                    let quantity = quantitySample.quantity
                    let heightUnit = HKUnit.count()
                    let usersHeight = quantity.doubleValue(for:heightUnit)
                    totalSteps += usersHeight
                }
                totalClosure(totalSteps, error)
                String.dLog(logMsg: String(format: "当天行走步数%.0f", totalSteps))
            }
            
        }
        
        healthStore?.execute(query)
    }
    
    // 读取步行 + 跑步距离
    public func getDistance(totalClosure: @escaping totalClosure)
    {
        let WalkingRunning = HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning)
        
        let timeSortDescriptor = NSSortDescriptor.init(key:HKSampleSortIdentifierEndDate, ascending: false)
        
        let query = HKSampleQuery.init(sampleType:WalkingRunning!, predicate: predicateForSamplesToday(), limit: 0, sortDescriptors: [timeSortDescriptor]) { (query, results, error) in
            
            if let err: Error = error {
                totalClosure(0, err)
            }else{
                
                var  totalSteps:Double = 0.0;
                
                for i in 0 ..< (results?.count)! {
                    let quantitySample =  results?[i] as! HKQuantitySample
                    let quantity = quantitySample.quantity
                    let kiloUnit = HKUnit.meterUnit(with: .kilo)
                    let usersHeight = quantity.doubleValue(for: kiloUnit)
                    totalSteps += usersHeight
                    
                }
                
                totalClosure(totalSteps, error)
                String.dLog(logMsg: String(format: "当天行走距离%.0f", totalSteps))
            }
            
            
            
        }
        
        healthStore?.execute(query)
    }
    
    /**
     NSPredicate 当天时间段的方法实现
     - brief  当天时间段
     - return 时间段
     */
    fileprivate func predicateForSamplesToday() -> NSPredicate {
        
        let calendar = Calendar.current
        
        let set = Set.init(arrayLiteral:Calendar.Component.year,Calendar.Component.month,Calendar.Component.day)
        
        var components = calendar.dateComponents(set, from: Date.init())
        
        components.hour = 0
        components.minute = 0
        components.second = 0
        
        let startDate = calendar.date(from: components)
        let endDate = Date().localNow
        let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .init(rawValue: 0))
        return predicate
    }
}
manager类调用:

    // 获取步数
    fileprivate func stepCount()
    {
        BBSHealthKitManager.shareInstance.authorizeHealthKit { (success: Bool, error: Error?) in
            if success {
                BBSHealthKitManager.shareInstance.getStepCount {
                    (value: Double, error: Error?) in
                    DispatchQueue.main.async(execute: {
                        self.step = value  // 得到value 步数
                    })
                }
            } else {
                print(error?.localizedDescription)
            }
        }
    }

获取距离与上面代码相似

参考博客: 

http://www.jianshu.com/p/8f896172fb3d

http://www.jianshu.com/p/1dd6ad5b1520

简书博客地址

https://www.jianshu.com/u/3c7c13f3dc6b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值