天天看點

HealthKit之實戰讀取步數、活動時長、運動距離、已爬樓層、活動能量、健身記錄

- (void)querystepcount

{

    if (![hkhealthstore ishealthdataavailable])

    {

        nslog(@"裝置不支援healthkit"); return;

    }

    _healthstore = [[hkhealthstore alloc] init];

    hkobjecttype *type1 = [hkobjecttype quantitytypeforidentifier:hkquantitytypeidentifierstepcount]; // 步數

    hkobjecttype *type2 = [hkobjecttype quantitytypeforidentifier:hkquantitytypeidentifierdistancewalkingrunning]; // 步行+跑步距離

    hkobjecttype *type3 = [hkobjecttype quantitytypeforidentifier:hkquantitytypeidentifierflightsclimbed];     // 已爬樓層

    hkobjecttype *tyep4 = [hkobjecttype quantitytypeforidentifier:hkquantitytypeidentifieractiveenergyburned]; // 活動能量

    hkobjecttype *type5 = [hkobjecttype activitysummarytype];// 健身記錄

    nsset *set = [nsset setwithobjects:type1, type2, type3, tyep4, type5, nil]; // 讀集合

    __weak typeof (&*self) weakself = self;

    [_healthstore requestauthorizationtosharetypes:nil readtypes:set completion:^(bool success, nserror * _nullable error) {

        if (success)

        {

            [weakself readstepcount];

        } else

            nslog(@"healthkit不允許讀寫");

        }

    }];

}

//查詢資料

- (void)readstepcount

    hkquantitytype *sampletype = [hkquantitytype quantitytypeforidentifier:hkquantitytypeidentifierstepcount];

    //nssortdescriptors用來告訴healthstore怎麼樣将結果排序。

    nssortdescriptor *start = [nssortdescriptor sortdescriptorwithkey:hksamplesortidentifierstartdate ascending:no];

    nssortdescriptor *end   = [nssortdescriptor sortdescriptorwithkey:hksamplesortidentifierenddate ascending:no];

    /*查詢的基類是hkquery,這是一個抽象類,能夠實作每一種查詢目标,這裡我們需要查詢的步數是一個

     hksample類是以對應的查詢類就是hksamplequery。

     下面的limit參數傳1表示查詢最近一條資料,查詢多條資料隻要設定limit的參數值就可以了

     */

    nscalendar *calendar = [[nscalendar alloc] initwithcalendaridentifier:nscalendaridentifiergregorian];

    nsdatecomponents *datecom = [calendar components:nsyearcalendarunit | nsmonthcalendarunit | nsdaycalendarunit | nshourcalendarunit | nsminutecalendarunit | nssecondcalendarunit fromdate:[nsdate date]];

    nsdate *startdate, *enddate;

    enddate = [calendar datefromcomponents:datecom];

    [datecom sethour:0];

    [datecom setminute:0];

    [datecom setsecond:0];

    startdate = [calendar datefromcomponents:datecom];

    nspredicate *predicate = [hkquery predicateforsampleswithstartdate:startdate enddate:enddate options:hkqueryoptionstrictstartdate];

    __weak typeof (&*_healthstore)weakhealthstore = _healthstore;

    hksamplequery *q1 = [[hksamplequery alloc] initwithsampletype:sampletype predicate:predicate limit:hkobjectquerynolimit sortdescriptors:@[start,end] resultshandler:^(hksamplequery * _nonnull query, nsarray<__kindof hksample *> * _nullable results, nserror * _nullable error) {

        double sum = 0;

        double sumtime = 0;

        nslog(@"步數結果=%@", results);

        for (hkquantitysample *res in results)

            sum += [res.quantity doublevalueforunit:[hkunit countunit]];

            nstimezone *zone = [nstimezone systemtimezone];

            nsinteger interval = [zone secondsfromgmtfordate:res.enddate];

            nsdate *startdate = [res.startdate datebyaddingtimeinterval:interval];

            nsdate *enddate   = [res.enddate datebyaddingtimeinterval:interval];

            sumtime += [enddate timeintervalsincedate:startdate];

            [[nsoperationqueue mainqueue] addoperationwithblock:^{

                //查詢是在多線程中進行的,如果要對ui進行重新整理,要回到主線程中

                self.title = [nsstring stringwithformat:@"運動步數:%@", @(sum).stringvalue];

            }];

        int h = sumtime / 3600;

        int m = ((long)sumtime % 3600)/60;

        nslog(@"運動時長:%@小時%@分", @(h), @(m));

        nslog(@"運動步數:%@步", @(sum));

        if(error) nslog(@"1error==%@", error);

        [weakhealthstore stopquery:query];

        nslog(@"\n\n");

    hksampletype *timesampletype = [hkquantitytype quantitytypeforidentifier:hkquantitytypeidentifierdistancewalkingrunning];

    hksamplequery *q2 = [[hksamplequery alloc] initwithsampletype:timesampletype predicate:predicate limit:hkobjectquerynolimit sortdescriptors:@[start,end] resultshandler:^(hksamplequery * _nonnull query, nsarray<__kindof hksample *> * _nullable results, nserror * _nullable error) {

        double time = 0;

            time += [res.quantity doublevalueforunit:[hkunit meterunit]];

        nslog(@"運動距離===%@米", @((long)time));

        if(error) nslog(@"2error==%@", error);

    hksampletype *type3 = [hkquantitytype quantitytypeforidentifier:hkquantitytypeidentifierflightsclimbed];

    hksamplequery *q3 = [[hksamplequery alloc] initwithsampletype:type3 predicate:predicate limit:hkobjectquerynolimit sortdescriptors:@[start,end] resultshandler:^(hksamplequery * _nonnull query, nsarray<__kindof hksample *> * _nullable results, nserror * _nullable error) {

        double num = 0;

            num += [res.quantity doublevalueforunit:[hkunit countunit]];

        nslog(@"樓層===%@層", @(num));

        if(error) nslog(@"3error==%@", error);

    hksampletype *type4 = [hkquantitytype quantitytypeforidentifier:hkquantitytypeidentifieractiveenergyburned];

    hksamplequery *q4 = [[hksamplequery alloc] initwithsampletype:type4 predicate:predicate limit:hkobjectquerynolimit sortdescriptors:@[start,end] resultshandler:^(hksamplequery * _nonnull query, nsarray<__kindof hksample *> * _nullable results, nserror * _nullable error) {

            num += [res.quantity doublevalueforunit:[hkunit kilocalorieunit]];

        nslog(@"卡路裡===%@大卡", @((long)num));

        if(error) nslog(@"4error==%@", error);

    nsdatecomponents *datecom5b = [calendar components:nsyearcalendarunit | nsmonthcalendarunit | nsdaycalendarunit fromdate:[nsdate date]];

    [datecom5b setday:(datecom5b.day - 10)];

    datecom5b.calendar = calendar;

    nsdatecomponents *datecom5e = [calendar components:nsyearcalendarunit | nsmonthcalendarunit | nsdaycalendarunit fromdate:[nsdate date]];

    datecom5e.calendar = calendar;

    nspredicate *predicate5 = [hkactivitysummaryquery predicateforactivitysummarywithdatecomponents:datecom5b];

//    nspredicate *predicate5 = [hkactivitysummaryquery predicateforactivitysummariesbetweenstartdatecomponents:datecom5b enddatecomponents:datecom5e];

    hkactivitysummaryquery *q5 = [[hkactivitysummaryquery alloc] initwithpredicate:predicate5 resultshandler:^(hkactivitysummaryquery * _nonnull query, nsarray<hkactivitysummary *> * _nullable activitysummaries, nserror * _nullable error) {

        double energynum       = 0;

        double exercisenum     = 0;

        double standnum        = 0;

        double energygoalnum   = 0;

        double exercisegoalnum = 0;

        double standgoalnum    = 0;

        for (hkactivitysummary *summary in activitysummaries)

            energynum       += [summary.activeenergyburned doublevalueforunit:[hkunit kilocalorieunit]];

            exercisenum     += [summary.appleexercisetime doublevalueforunit:[hkunit secondunit]];

            standnum        += [summary.applestandhours doublevalueforunit:[hkunit countunit]];

            energygoalnum   += [summary.activeenergyburnedgoal doublevalueforunit:[hkunit kilocalorieunit]];

            exercisegoalnum += [summary.appleexercisetimegoal doublevalueforunit:[hkunit secondunit]];

            standgoalnum    += [summary.applestandhoursgoal doublevalueforunit:[hkunit countunit]];

        nslog(@"健身記錄:energynum=%@",       @(energynum));

        nslog(@"健身記錄:exercisenum=%@",     @(exercisenum));

        nslog(@"健身記錄:standnum=%@",        @(standnum));

        nslog(@"健身記錄:energygoalnum=%@",   @(energygoalnum));

        nslog(@"健身記錄:exercisegoalnum=%@", @(exercisegoalnum));

        nslog(@"健身記錄:standgoalnum=%@",    @(standgoalnum));

        if(error) nslog(@"5error==%@", error);

    //執行查詢

    [_healthstore executequery:q1];

    [_healthstore executequery:q2];

    [_healthstore executequery:q3];

    [_healthstore executequery:q4];

    [_healthstore executequery:q5];

繼續閱讀