title: How to get daily sleep duration using Apple HealthKit?
body: <p>I'm doing an app that reads daily steps and sleep data from Apple HealthKit. </p>
  
  <p>For <strong>Steps</strong>, it's pretty easy because it is a <code>HKQuantityType</code>, so I can apply <code>HKStatisticsOptionCumulativeSum</code> option on it. Put the start date, end date, and date interval in, and you got it.</p>
  
  <pre><code>- (void)readDailyStepsSince:(NSDate *)date completion:(void (^)(NSArray *results, NSError *error))completion {
      NSDate *today = [NSDate date];
      NSCalendar *calendar = [NSCalendar currentCalendar];
      NSDateComponents *comps = [calendar components:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:date];
      comps.hour = 0;
      comps.minute = 0;
      comps.second = 0;
  
      NSDate *midnightOfStartDate = [calendar dateFromComponents:comps];
      NSDate *anchorDate = midnightOfStartDate;
  
      HKQuantityType *stepType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
      HKStatisticsOptions sumOptions = HKStatisticsOptionCumulativeSum;
      NSPredicate *dateRangePred = [HKQuery predicateForSamplesWithStartDate:midnightOfStartDate endDate:today options:HKQueryOptionNone];
  
      NSDateComponents *interval = [[NSDateComponents alloc] init];
      interval.day = 1;
      HKStatisticsCollectionQuery *query = [[HKStatisticsCollectionQuery alloc] initWithQuantityType:stepType quantitySamplePredicate:dateRangePred options:sumOptions anchorDate:anchorDate intervalComponents:interval];
  
      query.initialResultsHandler = ^(HKStatisticsCollectionQuery *query, HKStatisticsCollection *result, NSError *error) {
  
          NSMutableArray *output = [NSMutableArray array];
  
          // we want "populated" statistics only, so we use result.statistics to iterate
          for (HKStatistics *sample in result.statistics) {
              double steps = [sample.sumQuantity doubleValueForUnit:[HKUnit countUnit]];
              NSDictionary *dict = @{@"date": sample.startDate, @"steps": @(steps)};
              //NSLog(@"[STEP] date:%@ steps:%.0f", s.startDate, steps);
              [output addObject:dict];
          }
  
          dispatch_async(dispatch_get_main_queue(), ^{
              if (completion != nil) {
                  NSLog(@"[STEP] %@", output);
                  completion(output, error);
              }
          });
      };
  
      [self.healthStore executeQuery:query];
  }
  </code></pre>
  
  <p>But for <strong>Sleep</strong> it's not so straight forward. There are many things I stuck on.</p>
  
  <ul>
  <li>First, unlike steps, sleep is a <code>HKCategoryType</code>. So we cannot use <code>HKStatisticsCollectionQuery</code> to sum it because this method only accepts <code>HKQuantityType</code>.</li>
  <li>Also there are 2 value types of sleep, <code>HKCategoryValueSleepAnalysisInBed</code> and <code>HKCategoryValueSleepAnalysisAsleep</code>. I'm not sure which value is best for just the sleep duration. I'll just use <code>HKCategoryValueSleepAnalysisAsleep</code> only for simplicity.</li>
  <li>Sleep data comes in an array of <code>HKCategorySample</code> objects. Each with start date and end date. How do I effectively combine those data, trim it to within a day, and get the daily sleep duration (in minutes) out of it? I found this <strong>DTTimePeriodCollection</strong> class in <a href="https://github.com/MatthewYork/DateTools" rel="nofollow">DateTool</a> pod that may do this job, but I haven't figure it out yet.</li>
  </ul>
  
  <p>Simply put, if anyone knows how to get daily sleep duration using Apple HealthKit, please tell me!</p>