如今不少应用中加入了健康这个模块, 像微信一样展示每天运动步数或其他数据, 那么我们如何获取这些数据呢?
新建一个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
简书博客地址