有关HealthKit的那些事

有关HealthKit的那些事--北京尚学堂

最近在做项目的时候,突然接到产品经理给的一个需求,要求在项目中统计用户每日步数,具体要求就是获取手机健康应用中统计的每日步数,然后以图形方式显示。

刚听到这个需求的时候就想到了苹果在iOS 8系统推出之时顺带出的HealthKit框架,不过对于其API倒是非常的陌生。于是就开始在网上查找资料,百度,谷歌一番之后,发现也未能找到一个资料能够很好地引导新手使用该框架(可能是我没找到好的-_-!),经过几天的个人摸索,也算是有点心得体会,在这里就将自己对该框架相关的使用做个梳理,也希望能够为接下来即将接触和使用该框架的童鞋提供一点小小的帮助。如有什么疑问或者不对的地方欢迎提出。以下内容以获取步数为例,其他数据获取可以此类推。

一、项目中关联HealthKit框架

HealthKit关联路径

首先填写好你项目的Bundle Identifier并且选好Team(这两个东西最好事先设置好,以免之后又得重新关联),然后在项目物理文件结构中点选对应的项目,在TARGETS中选择你自身的项目,再在右侧选择Capabilities选项。

HealthKit

从中找到HealthKit这项,点击右侧的开关开启,当出现中间红框所示的内容,表示项目与HealthKit框架关联成功了

成功关联HealthKit

你会在项目中看到多了HealthKit.framework和.entitlements结尾的这两个文件,OK一切顺利,接下来就可以Code了。

二、HealthKit所支持的系统和设备

因为HealthKit框架是在iOS8系统出来之时一同推出的,所以该框架目前只支持iOS8及以上系统,目前支持的设备有iPhone、iWatch,要记得iPad是不支持的哦,如果你的代码同时支持iPhone和iPad设备,那么记得判断下设备还有系统版本号,以免出现不必要的奔溃现象。在项目中导入后,你也可以使用以下代码判断该设备的系统能否使用健康数据:


1


[HKHealthStore isHealthDataAvailable]

三、应用授权

要想获取健康数据中的步数,则需要通过用户许可才行。具体可以使用以下代码进行授权:


1

2

3

4

5

6

7

8

9


HKHealthStore *healthStore = [[HKHealthStore alloc] init];

NSSet *readObjectTypes = [NSSet setWithObjects:[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount], nil];

[healthStore requestAuthorizationToShareTypes:nil readTypes:readObjectTypes completion:^(BOOL success, NSError *error) {

if (success == YES)  {

//授权成功

} else {

//授权失败

}

}];

这里调用了requestAuthorizationToShareTypes:readTypes: completion:方法,用于对应用授权需要获取和分享的健康数据:

·        第一个参数传入一个NSSet类型数据,用于告知用户,我的app可能会在你的健康数据库中修改这些选项数据(显然目前我们不需要,传nil)。

·        第二个参数也是传入NSSet类型数据,告知用户,我的app可能会从你的数据库中读取以下几项数据。

·        第三个是授权许可回调,BOOL值success用于区分用户是否允许应用向数据库存取数据。

四、获取健康步数

授权完成之后,我们接下来就可以调用API来获取数据库数据了。


1

2

3

4

5

6

7

8

9

10

11

12

13


HKSampleType *sampleType = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];

NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:nil endDate:nil options:HKQueryOptionStrictStartDate];

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierStartDate ascending:YES];

HKSampleQuery *sampleQuery = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:predicate limit:HKObjectQueryNoLimit sortDescriptors:@[sortDescriptor] resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {

if(!error && results) {

for(HKQuantitySample *samples in results) {

NSLog(@"%@ 至 %@ : %@", samples.startDate, samples.endDate, samples.quantity);

}

} else {

//error

}

}];

[healthStore executeQuery:sampleQuery];

这段代码主要做了以下几件事情:

·        第一段通过传入一个枚举值HKQuantityTypeIdentifierStepCount来创建一个样品类的实例,用于告知,我接下来要获取的数据是步数。

·        第二段代码通过创建一个NSPredicate类的实例,用于获取在某个时间段的数据,这里startDate和endDate传入nil,表示获取全部数据,第三个参数传入一个Option,里面有三个值,这个参数我试验了下不同的值代入,发现返回的结果都是一样的,要是有谁知道这个值是做什么用的麻烦告知我一声~

·        第三段代码创建了一个NSSortDescriptor类实例,用于对查询的结果排序。

·        第四段代码通过调用HKSampleQuery类的实例方法获取所需数据

·        最后一行代码用于执行数据查询操作

通过这段代码获取的数据,打印出来会发现,它获取的是比较详尽的数据,精确到每一小段时间从开始时间到结束时间内所获取的步数。

五、数据采集

有时候需求并不需要了解这么详尽的数据,只希望获取每小时、每天或者每月的步数,那么我们就需要用到另一个新类HKStatisticsCollectionQuery进行数据的分段采集


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15


HKQuantityType *quantityType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];

NSDateComponents *dateComponents = [[NSDateComponents alloc] init];

dateComponents.day = 1;

HKStatisticsCollectionQuery *collectionQuery = [[HKStatisticsCollectionQuery alloc] initWithQuantityType:quantityType quantitySamplePredicate:nil options: HKStatisticsOptionCumulativeSum | HKStatisticsOptionSeparateBySource anchorDate:[NSDate dateWithTimeIntervalSince1970:0] intervalComponents:dateComponents];

collectionQuery.initialResultsHandler = ^(HKStatisticsCollectionQuery *query, HKStatisticsCollection * __nullable result, NSError * __nullable error) {

for (HKStatistics *statistic in result.statistics) {

NSLog(@"\n%@ 至 %@", statistic.startDate, statistic.endDate);

for (HKSource *source in statistic.sources) {

if ([source.name isEqualToString:[UIDevice currentDevice].name]) {

NSLog(@"%@ -- %f",source, [[statistic sumQuantityForSource:source] doubleValueForUnit:[HKUnit countUnit]]);

}

}

}

};

[healthStore executeQuery:collectionQuery];

·        第一段代码所做的和之前的一样,定义需要获取的数据为步数。

·        第二段代码创建一个NSDateComponents类实例,设置我要获取的步数时间间隔,这里设置为按天统计,这里也可以设置按小时或者按月统计

·        第三段代码创建查询统计对象collectionQuery,通过传入四个参数进行初始化:

a.第一个参数同上面一样,设置需要查询的类型

b.第二个参数传入一个NSPredicate实例,目前这里传nil

c.第三个参数是关键,传入一个Option可选值,告诉查询统计对象我需要获取的是啥,这里传入HKStatisticsOptionCumulativeSum |HKStatisticsOptionSeparateBySource值,获取时间段的步数和以及将数据根据不同的数据来源进行分段

d.第四个参数传入一个锚点,类似于数组的索引值,查询将会从改锚点开始查询,这里可以根据不同的锚点值,获取日/周/月/年数据

·        第四段代码是将collectionQuery对象的block属性initialResultsHandler进行赋值,该block会在数据查询成功之后进行回调,从中可以获得我们想要的数据5、最后一行执行该查询统计操作执行这段代码,通过打印的日志可以看到当前设备中存储的按日间隔存储的步行数总和了。

返回的数据中HKSource对象中的name可用于区分健康数据来源,一般只获取设备中的步数,过滤其他第三方数据来源,目前微信、QQ所用的记步就是区分了不同的数据来源,防止作弊!!!

更多ios内容请见:www.bjsxt.com

时间: 2024-09-30 12:14:21

有关HealthKit的那些事的相关文章

HealthKit开发教程Swift版:起步

原文:HealthKit Tutorial with Swift: Getting Started 作者:Ernesto García 译者:Mr_cyz ) HealthKit是iOS 8中的新的API,它提供了一种优雅的方式来获取和存储用户的健康数据. 在本篇HealthKit教程中,你将会创建一个简单地记录用户信息的app.在此过程中,你会学到许多关于HealthKit的知识,例如: 怎么样向用户请求允许来获得HealthKit的数据 怎么样读取信息然后将其格式化展示在屏幕上 怎么样将数据

关于打码的一些事

1.今晚打代码算是遇到好多问题了,但是谷歌,stackoverflow,谷歌翻译,一点点都解决了,问别人也没回,所以说还是靠自己,记得更久一些,自己栽过的坑,印象会更深刻. 2.静下心来做一件事,很多事情没想象的那么难的. 3.喜欢这种学习后的充实感,不会像打完游戏或者看完视频一样迷茫. 4.继续加油吧. 5.原来右键网页图片可以get到url.

10682 deathgod想知道的事(数论)

10682 deathgod想知道的事 该题有题解 时间限制:1000MS  内存限制:65535K提交次数:265 通过次数:14 题型: 编程题   语言: G++;GCC Description 一只蚂蚁从衣服地图上爬过留下痕迹,deathgod看到后在地图上建了个坐标,将蚂蚁留下的痕迹分成多条线段首位相连而成, 且那些线段的端点都是整数点,现在他想知道这只蚂蚁经过了坐标中多少个整数点. 输入格式 第一行输入一个整数t,表示case数:对于每个case,第一行输入一个整数n(0<=n<=

转 离婚前夜悟出的三件事

文/铁眼(简书作者)原文链接:http://www.jianshu.com/p/832be4f659a0?utm_campaign=hugo&utm_medium=reader_share&utm_content=note著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 前两天,在一次吃饭的时候,感觉嘴里有异样,用牙签一挑,一颗智齿酥了,脱落下来.当时很惊恐,自己才30多点,牙齿就坏了,那时只有后悔的想法,如果再往回调两年时间,我一定好好认真的刷牙,保养好牙齿. 牙齿如此坚固

专业房产经纪人必须知道的九件事

1 顾客说的话不全信 顾客是上帝,但是上帝从来不会把自己的心交给他的下人.80%的顾客因为对你抱有戒心,所以他是不会把自己的真实承受价格告诉你的,当然这种留有余地的做法是人之常情.你要做的不过是告诉顾客你是多么的专业就可以了,你要让顾客相信你,这样,你的工作才能完成. 2 永远不要对顾客说没有 永远不要对顾客说没有,即便顾客的要求非常无理.我们接到一个电话,可能是形形***的,有细心询问,有侃侃而谈,我们怎么在一个电话间去判断这个顾客?如果判断对了,顾客对你的信任度就会加强,接下来一切工作都好办

[java学习笔记]Hello World那些事

我们安装和配置好java后,必须得大展拳脚一番,根据国际惯例,第一个程序必须是Hello World,下面我们就看看Hello World的那些事. 1.Hello World的运行 Hello World流程: 将java代码编写到.java后缀的文件中保存. 通过javac编译命令对该.java文件进行编译(编译后产生.class文件). 通过Java命令运行产生的,class文件. 流程图:   F:\Demo.java文件内容: public class Demo{ public sta

做正确的事,不做容易的事

原文<李想:"做正确的事,不做容易的事"> 本文是我(李想)在去经纬投资和他们聊天的时候,速记员帮助我把聊天的内容记录了下来的整理.因为内容量很大,所以速记会有一些记录错误的地方.我想了一下,还是使用原文重新整理了一遍,把里面的错字和错误的数据进行了修改,从而避免对阅读者的误导. 不过,仍然感谢经纬和速记的帮助,这确实是我过去十几年创业最实实在在的记录. 我也开通了长微博打赏的功能,各位大爷看的好,赏几个零花钱! 李想,汽车之家网站创始人,前任汽车之家总裁.李想是80后的典

开发人员转型到管理者必须学会的7件事

技术工程师的晋升之路 技术工程师的晋升之路大体上可以分为两个方向,一是在技术方向上作为Individual Contributor(IC)继续深造,二是以管理者的身份管理工程师团队.IC这条路比较单纯,能走多远主要取决于个人的技术实力与经验.与IC相比,转型为管理者可以说是一种颠覆性的变化.管理者的工作不再是以个人或项目的成功作为主要目标,而是专注于整个团队的成功.这种目标的变化将直接改变管理者的心态与工作方式,以及与他人的互动方式.可以说,向管理者的转型是一个具有更大挑战性的选择. David

想提升工作效率,就別再做这七件事

试想一位小公司老板每日孜孜不倦地工作,为何不能从为数众多的竞争者脱颖而出? 一位创业家可以不眠不休一天工作24 小时,整整一周不休假. 然而,时间有限,且竞争者却永远可以投入更多钱与心力,让竞争更剧烈.那么,为什么某些小型新创公司可以完成许多大型企业无法完成的事情呢? ●Instagram──只有13 名员工却被Facebook 用几十亿买下的公司. ●Snapchat──只有30 名员工却拒绝科技巨人Facebook.Google 的并购交易. 它们的成功部分来自于幸运──其余则是因为效率 .