//
// J_HelthKitViewController.m
// ThirdFrameworksDemo
//
// Created by jyf on 2018/5/15.
// Copyright © 2018年 jyf. All rights reserved.
//
#import "J_HelthKitViewController.h"
#import <HealthKit/HealthKit.h>
#import <BlocksKit/UIControl+BlocksKit.h>
@interface J_HelthKitViewController ()
@property (nonatomic, strong)HKHealthStore *HKStore;
@property (nonatomic,strong) UILabel *countLabel;
@end
/*
主要枚举:HKQuantityTypeIdentifierBodyMassIndex:体重指数
HKQuantityTypeIdentifierBodyFatPercentage:体脂率
HKQuantityTypeIdentifierHeight:身高
HKQuantityTypeIdentifierBodyMass:体重
HKQuantityTypeIdentifierLeanBodyMass:去脂体重
HKQuantityTypeIdentifierStepCount:行走步数
HKQuantityTypeIdentifierDistanceWalkingRunning:走跑距离
HKQuantityTypeIdentifierDistanceCycling:骑行距离
HKQuantityTypeIdentifierDistanceWheelchair:轮椅距离(喵喵喵?)
HKQuantityTypeIdentifierBasalEnergyBurned:基础能量消耗/静息能量消耗
HKQuantityTypeIdentifierActiveEnergyBurned:活动能量消耗
HKQuantityTypeIdentifierFlightsClimbed:爬升距离/已爬楼层
HKQuantityTypeIdentifierAppleExerciseTime:锻炼时间
HKQuantityTypeIdentifierPushCount:推动次数
HKQuantityTypeIdentifierDistanceSwimming:游泳距离 (这两项可能要手表数据,水果机不防水的吧
HKQuantityTypeIdentifierSwimmingStrokeCount:划水次数
HKQuantityTypeIdentifierHeartRate:心率
HKQuantityTypeIdentifierBodyTemperature:体温
HKQuantityTypeIdentifierBasalBodyTemperature 基础体温
HKQuantityTypeIdentifierBloodPressureSystolic 收缩血压/高压
HKQuantityTypeIdentifierBloodPressureDiastolic 舒张血压/低压
HKQuantityTypeIdentifierRespiratoryRate:呼吸频率
*/
@implementation J_HelthKitViewController
#pragma mark -------------------------- viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
[self function_setSubViews];
[self function_getHealthKitAnthorization];
}
#pragma mark -------------------------- 添加字视图
- (void)function_setSubViews {
self.countLabel = [[UILabel alloc]init];
self.countLabel.textColor = [UIColor randomFlatColor];
self.countLabel.font = [UIFont boldSystemFontOfSize:30];
self.countLabel.numberOfLines = 0;
self.countLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.countLabel];
[self.countLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(10);
make.top.mas_equalTo(100);
}];
UIButton *writeCountStepBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[writeCountStepBtn setTitle:@"写入步数" forState:UIControlStateNormal];
[writeCountStepBtn bk_addEventHandler:^(id sender) {
[self addstepWithStepNum:20000];
} forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:writeCountStepBtn];
[writeCountStepBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(100);
make.height.mas_equalTo(40);
make.width.mas_equalTo(100);
make.top.equalTo(self.countLabel.mas_bottom).offset(100);
}];
}
#pragma mark -------------------------- 请求健康数据读写权限
- (void)function_getHealthKitAnthorization {
self.HKStore = [[HKHealthStore alloc]init];
//将你想查询的数据类型各自设置一个HKObjectTyoe,然后放进下面的NSSet中
HKObjectType *stepType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];//步数
NSSet *healthSet = [NSSet setWithObjects:stepType, nil];
HKObjectType *heartType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];//心率
NSSet *readSet = [NSSet setWithObjects:heartType, nil];
//shareTypesSet设置的是需要写入数据的NSset集合,readTypes设置的是读取数据的NSSet
//返回结果中,如果success == true,则授权成功,开始进行读取操作
[self.HKStore requestAuthorizationToShareTypes:readSet readTypes:readSet completion:^(BOOL success, NSError * _Nullable error) {
if (success) {
NSLog(@"success");
[self function_requestData];
}else{
kLog(@"false-->%@",error);
}
}];
[self.HKStore requestAuthorizationToShareTypes:healthSet readTypes:healthSet completion:^(BOOL success, NSError * _Nullable error) {
if (success) {
NSLog(@"success");
[self function_requestData];
}else{
kLog(@"false-->%@",error);
}
}];
}
#pragma mark -------------------------- 整理数据,获取步数信息
- (void)function_requestData {
//设置你需要查询的采样信息
//所有的查询类都是基于抽象类HKQuery,这里我们用查询步数来举例,步数对应的类是HKSample类,所以我们需要实例化一个HKSampleQuery对象
HKSampleType *sampleType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
//NSSortDescriptor类是排序规则描述类,start规则描述了按照HKSample的运动开始时间startTimestamp降序排序
//同理end描述了按照运动的结束时间endTimestamp降序排序
//@[start end]的排序描述的规则是:首先按照运动开始时间排序,如果开始时间相同,则按照结束时间降序排序
NSSortDescriptor *start = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierStartDate ascending:NO];
NSSortDescriptor *end = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierEndDate ascending:NO];
//设置查询时间
NSDate *now = [NSDate date];
NSCalendar *calender = [NSCalendar currentCalendar];
NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
//将当前时间按照上述格式分割成年月日时分秒六个数字,然后提取时分秒
NSDateComponents *dateComponent = [calender components:unitFlags fromDate:now];
int hour = (int)[dateComponent hour];
int minute = (int)[dateComponent minute];
int second = (int)[dateComponent second];
//当前时间点 减去今天已经过去的时分秒 加上东八区时差补偿 = 今天开始的00:00分
NSDate *today = [NSDate dateWithTimeIntervalSinceNow: - (hour*3600 + minute * 60 + second) + 28800];
NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow: - (hour*3600 + minute * 60 + second) + 28800 + 86400];
//设置查询范围为今天到明天的24小时内
NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:today endDate:tomorrow options:HKQueryOptionNone];
HKSampleQuery *query = [[HKSampleQuery alloc]initWithSampleType:sampleType predicate:predicate limit:HKObjectQueryNoLimit sortDescriptors:@[start,end] resultsHandler:^(HKSampleQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable results, NSError * _Nullable error) {
if (results.count > 0) {
kLog(@"查询成功-->%@",results);
NSInteger count = 0;
for (HKQuantitySample *sample in results) {
NSString *str = [NSString stringWithFormat:@"%@",sample.quantity];
kLog(@"%@",str);
NSString *str2 = [str componentsSeparatedByString:@" "][0];
NSInteger step = [str2 integerValue];
count += step;
}
dispatch_async(dispatch_get_main_queue(), ^{
self.countLabel.text = [NSString stringWithFormat:@"截至目前\r\n今天共走了-->%ld步",count];
});
kLog(@"截至目前,共走了-->%ld 步",count);
}
}];
[self.HKStore executeQuery:query];
}
#pragma mark - **************** 写入步数
- (void)addstepWithStepNum:(double)stepNum {
// Create a new food correlation for the given food item.
HKQuantitySample *stepCorrelationItem = [self stepCorrelationWithStepNum:stepNum];
[self.HKStore saveObject:stepCorrelationItem withCompletion:^(BOOL success, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (success) {
[self.view endEditing:YES];
UIAlertView *doneAlertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"添加成功" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[doneAlertView show];
}
else {
NSLog(@"The error was: %@.", error);
UIAlertView *doneAlertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"添加失败" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[doneAlertView show];
return ;
}
});
}];
}
- (HKQuantitySample *)stepCorrelationWithStepNum:(double)stepNum {
NSDate *endDate = [NSDate date];
NSDate *startDate = [NSDate dateWithTimeInterval:-300 sinceDate:endDate];
HKQuantity *stepQuantityConsumed = [HKQuantity quantityWithUnit:[HKUnit countUnit] doubleValue:stepNum];
HKQuantityType *stepConsumedType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKDevice *device = [[HKDevice alloc] initWithName:@"iPhone" manufacturer:@"Apple" model:@"iPhone" hardwareVersion:@"iPhone6s plus" firmwareVersion:@"iPhone6s plus" softwareVersion:@"9.3.1" localIdentifier:@"aaron" UDIDeviceIdentifier:@"aaron"];
// NSDictionary *stepCorrelationMetadata = @{HKMetadataKeyUDIDeviceIdentifier: @"aaron's test equipment",
// HKMetadataKeyDeviceName:@"iPhone",
// HKMetadataKeyWorkoutBrandName:@"Apple",
// HKMetadataKeyDeviceManufacturerName:@"Apple"};
HKQuantitySample *stepConsumedSample = [HKQuantitySample quantitySampleWithType:stepConsumedType quantity:stepQuantityConsumed startDate:startDate endDate:endDate device:device metadata:nil];
return stepConsumedSample;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
网友评论