美文网首页
获取健康数据

获取健康数据

作者: 蜗牛1992 | 来源:发表于2016-11-22 13:50 被阅读145次
    #import <Foundation/Foundation.h>
    #import <HealthKit/HealthKit.h>
    #import "HealthKitUtil.h"
    typedef long long long64;
    @interface HealthKitUtil : NSObject
    
    @property (strong, nonatomic) HKHealthStore *healthStore;
    @property (assign, nonatomic) BOOL isGetAuth;
    
    /**
     *  获取JHCHealthKitUtil单例
     *
     *  @return 单例
     */
    +(HealthKitUtil *)shareHealthUtil;
    
    /**
     *  读取健康应用指定时间当天的详细数据,组成json串输出
     *[{"step":"88","stime":"11:00","etime":"11:20","from":"iphone6s"{"step":"66","stime":"12:00","etime":"12:20","from":"iphone6s"}......]
     *
     *  @param pFIndentify   时间戳
     *  @param complete 读取完成的回调
     */
    -(void)readStepsDetailCountFromIndentify:(long64)indentify complete:(void(^)(BOOL success,NSString *pstrHealthDetail))complete;
    
    /**
     *  读取健康应用当天的总步数+总公里数
     *
     *  @param pstrHealthDate 步数&公里数 &号拼接 输出
     *  @param complete 读取完成的回调
     */
    -(void)readHealthDataFromIndentify:(long64)indentify Complete:(void(^)(BOOL success,NSString *pstrHealthDate))complete;
    
    /**
     *  获取健康应用授权
     *
     *  @param completion 完成后的回调方法
     */
    -(void) requestHealthAuthorizationCompletion:(void(^)(BOOL success))completion;
    
    @end
    
    #import "HealthKitUtil.h"
    static HealthKitUtil *pHealthKitUtil;
    @implementation HealthKitUtil
    
    +(HealthKitUtil *)shareHealthUtil
    {
        if (pHealthKitUtil == nil) {
            pHealthKitUtil = [[HealthKitUtil alloc]init];
            pHealthKitUtil.healthStore = [[HKHealthStore alloc]init];
        }
        return pHealthKitUtil;
    }
    //读取传入时间戳当天的步数详细信息,几点几分--几点几分走了多少步
    -(void)readStepsDetailCountFromIndentify:(long64)indentify complete:(void (^)(BOOL, NSString *pstrHealthDetail))complete
    {
        //时间戳转日期
        NSDate *pDate = [NSDate dateWithTimeIntervalSince1970:indentify/1000];
        NSCalendar *pCalendar = nil;
        if ([UIDevice currentDevice].systemVersion.doubleValue >= 8.0) {
            pCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
        } else {
            pCalendar = [NSCalendar currentCalendar];
        }
        //按照公历创建日期,
        NSDateComponents *pComponents = [pCalendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:pDate];
        //创建的Date是当前日期,默认时间为16:00:00(默认0时区) 即8时区的24:00:00
        NSDate *pStartDate = [pCalendar dateFromComponents:pComponents];
        //StartDate加一天
        NSDate *pEndDate = [pCalendar dateByAddingUnit:NSCalendarUnitDay value:1 toDate:pStartDate options:0];
    
        if (!_isGetAuth) {
            [self requestHealthAuthorizationCompletion:^(BOOL success) {
                if (success) {
                    _isGetAuth = YES;
                    [self readStepsDetailCountFromIndentify:indentify complete:complete];
                }
            }];
        }else{
            //查询采样信息
            HKSampleType *sampleType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
            //NSSortDescriptors用来告诉healthStore怎么样将结果排序。
            NSSortDescriptor *start = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierStartDate ascending:NO];
            NSSortDescriptor *end = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierEndDate ascending:NO];
            
            //    在结果中查找的条件 根据起止时间查找 results 结果数组
            NSPredicate *predicate_date = [NSPredicate predicateWithFormat:@"startDate >= %@ AND startDate <= %@", pStartDate,pEndDate];
            //    查询语句predicate:查询条件 limit:返回的数据数量 sortDescriptors:对结果排序
            HKSampleQuery *sampleQuery = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:predicate_date limit:0 sortDescriptors:@[start,end] resultsHandler:^(HKSampleQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable results, NSError * _Nullable error) {
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                    NSString *pstrHealthDate = @"";
                    for (HKQuantitySample *pSameple in results) {
                        //取出数组中单条数据
                        HKQuantity *quantity = pSameple.quantity;
                        //取出数据中开始时间,结束时间 转成时间戳毫秒,时间戳不分时区,所有时区时间戳一样的.
                        NSDate *pStart = pSameple.startDate;
                        long64 pStime = [pStart timeIntervalSince1970]*1000;
                        NSDate *pEnd = pSameple.endDate;
                        long64 pEtime = [pEnd timeIntervalSince1970]*1000;
                        //取出数据来源iPhone或者iPhone watch
                        HKDevice *pDevice = pSameple.device;
                        NSString *pstrDeviceName = pDevice.name;
                        //取出数据具体步数
                        NSUInteger iStep = [[quantity valueForKey:@"value"]integerValue];
                        //拼接字符串
                        NSString *pstrData = [NSString stringWithFormat:@"{\"step\":%lu,\"stime\":%lld,\"etime\":%lld,\"from\":%@},",iStep,pStime,pEtime,pstrDeviceName];
                        pstrHealthDate = [pstrHealthDate stringByAppendingString:pstrData];
                    }
                    //去掉最后的,
                    if (pstrHealthDate.length>0) {
                        pstrHealthDate = [pstrHealthDate substringToIndex:pstrHealthDate.length - 1 ];
                    }
                    //加[]
                    NSString *pstrHealthData = [NSString stringWithFormat:@"[%@]",pstrHealthDate];
                    if (nil !=results) {
                        if (complete) {
                            complete(YES,pstrHealthData);
                        }
                    }
                }];
            }];
            //执行查询
            [self.healthStore executeQuery:sampleQuery];
        }
    }
    
    //获取传入时间戳当天健康数据,总步数+总公里数,总步数&总公里数
    -(void)readHealthDataFromIndentify:(long64)indentify Complete:(void (^)(BOOL, NSString *pstrHealthDate))complete
    {
        //获取当天的数据
        NSDate *pDate = [NSDate dateWithTimeIntervalSince1970:indentify/1000];
        NSCalendar *pCalendar = nil;
        if ([UIDevice currentDevice].systemVersion.doubleValue >= 8.0) {
            pCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
        } else {
            pCalendar = [NSCalendar currentCalendar];
        }
        //按照公历创建日期,
        NSDateComponents *pComponents = [pCalendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:pDate];
        //创建的Date是当前日期,默认时间为16:00:00(默认0时区) 即8时区的24:00:00
        NSDate *pStartDate = [pCalendar dateFromComponents:pComponents];
        //StartDate加一天
        NSDate *pEndDate = [pCalendar dateByAddingUnit:NSCalendarUnitDay value:1 toDate:pStartDate options:0];
        
        if (!_isGetAuth) {
            [self requestHealthAuthorizationCompletion:^(BOOL success) {
                if (success) {
                    _isGetAuth = YES;
                    [self readHealthDataFromIndentify:indentify Complete:complete];
                }
            }];
        }else{
            //查询采样信息种类公里数,步数
            HKSampleType *pDistanceSampleType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning];
            HKSampleType *pStepSamletype = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
            //NSSortDescriptors用来告诉healthStore怎么样将结果排序。
            NSSortDescriptor *start = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierStartDate ascending:NO];
            NSSortDescriptor *end = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierEndDate ascending:NO];
            
            //    在结果中查找的条件 根据起止时间查找 results 结果数组
            NSPredicate *predicate_date = [NSPredicate predicateWithFormat:@"startDate >= %@ AND startDate <= %@", pStartDate,pEndDate];
            //记录总公里数
            __block double dDistance = 0;
            //    查询语句predicate:查询条件 limit:返回的数据数量 sortDescriptors:对结果排序
            HKSampleQuery *pDistanceSampleQuery = [[HKSampleQuery alloc] initWithSampleType:pDistanceSampleType predicate:predicate_date limit:0 sortDescriptors:@[start,end] resultsHandler:^(HKSampleQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable results, NSError * _Nullable error) {
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                    //查询是在多线程中进行的,如果要对UI进行刷新,要回到主线程中
                    for (HKQuantitySample *pSameple in results) {
                        HKQuantity *quantity = pSameple.quantity;
                        //单位KM
                        HKUnit *distanceUnit = [HKUnit meterUnitWithMetricPrefix:HKMetricPrefixKilo];
                        //公里数
                        double usersHeight = [quantity doubleValueForUnit:distanceUnit];
                        //计算总公里数
                        dDistance += usersHeight;
                    }
                }];
            }];
            //执行总公里数查询
            [self.healthStore executeQuery:pDistanceSampleQuery];
            //计算总步数
            __block NSUInteger iTotalCount = 0;
            //    查询语句predicate:查询条件 limit:返回的数据数量 sortDescriptors:对结果排序
            HKSampleQuery *pStepSampleQuery = [[HKSampleQuery alloc] initWithSampleType:pStepSamletype predicate:predicate_date limit:0 sortDescriptors:@[start,end] resultsHandler:^(HKSampleQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable results, NSError * _Nullable error) {
                //        NSLog(@"resultCount = %ld result = %@",results.count,results);
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                    //查询是在多线程中进行的,如果要对UI进行刷新,要回到主线程中
                    for (HKQuantitySample *pSameple in results) {
                        //获取单条数据
                        HKQuantity *quantity = pSameple.quantity;
                        //步数
                        double dStep = [[quantity valueForKey:@"value"]doubleValue];
                        //总步数
                        iTotalCount += dStep;
                    }
                    //拼接
                    NSString *pstrHealthDate = [NSString stringWithFormat:@"%lu&",(unsigned long)iTotalCount];
                    NSString *pstrDistance = [NSString stringWithFormat:@"%.2f",dDistance];
                    pstrHealthDate = [pstrHealthDate stringByAppendingString:pstrDistance];
                    if (nil != pstrHealthDate || pstrHealthDate.length > 0) {
                        if (complete) {
                            complete(YES,pstrHealthDate);
                        }
                    }
                }];
            }];
            //执行总步数查询
            [self.healthStore executeQuery:pStepSampleQuery];
        }
    }
    
    -(void) requestHealthAuthorizationCompletion:(void(^)(BOOL success))completion
    {
        //查看healthKit在设备上是否可用,ipad不支持HealthKit
        if(![HKHealthStore isHealthDataAvailable])
        {
            NSLog(@"设备不支持healthKit");
            completion(NO);
            return;
        }
        //设置需要获取的权限这里仅设置了步数,公里数
        HKObjectType *stepCount = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
        HKObjectType *stepDistance = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning];
        NSSet *healthSet = [NSSet setWithObjects:stepCount,stepDistance, nil];
        //从健康应用中获取权限
        [self.healthStore requestAuthorizationToShareTypes:nil readTypes:healthSet completion:^(BOOL success, NSError * _Nullable error) {
            if (success)
            {
                NSLog(@"获取健康健康步数+距离权限成功");
                _isGetAuth = YES;
                completion(YES);
            }
            else
            {
                NSLog(@"获取健康步数+距离权限失败");
                completion(NO);
            }
        }];
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:获取健康数据

          本文链接:https://www.haomeiwen.com/subject/nmippttx.html