HealthKit读取与修改步数

//
//  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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容