Skip to content

Instantly share code, notes, and snippets.

@bellebethcooper
Last active May 25, 2018 05:50
Show Gist options
  • Save bellebethcooper/194f149e4647df99fdf3539b2b73a944 to your computer and use it in GitHub Desktop.
Save bellebethcooper/194f149e4647df99fdf3539b2b73a944 to your computer and use it in GitHub Desktop.
- (NSArray <NSDictionary <NSString *, NSNumber *>*>*)weightValues:(int)numberOfValues
fromData:(NSArray <NSDictionary <NSString *, NSNumber *>*>*)healthKitData
usingDates:(NSArray <NSDate *>*)dates {
// Make a dictionary with a date string key
// (e.g. "2017-01-04") and a value of zero for each date
NSMutableDictionary *datesAndValues = [[NSMutableDictionary alloc] initWithCapacity:dates.count];
// Make an array of date strings to use when looping and comparing dates
NSMutableArray *dateStrings = [[NSMutableArray alloc] initWithCapacity:dates.count];
for (NSDate *date in dates) {
NSString *key = [BCDateHelper stringFromDate:date withFormat:ISO_DATE];
NSNumber *value = @0;
[datesAndValues setObject:value forKey:key];
[dateStrings addObject:key];
}
// This is the value we'll update each time we find a real weight
// And we'll use this to set real weight values for future dates that don't have a weight value
NSNumber *lastWeight = 0;
// Use string dates to compare to those returned in healthkit data
// Any healthkit data dictionaries with a date string matching one we're looping on
// gets its datesAndValues value updated to the real healthkit value
for (NSString *dateString in dateStrings) {
for (NSDictionary *dict in healthKitData) {
if ([[dict valueForKey:@"date"] isEqualToString:dateString]) {
[datesAndValues setValue:[dict valueForKey:@"value"] forKey:dateString];
// Set lastWeight to this real healthkit value
// to be used for future dates with no weight values
lastWeight = [dict valueForKey:@"value"];
// If there's no real healthkit value for this date,
// use lastWeight if it's not zero
} else if (lastWeight != 0) {
[datesAndValues setValue:lastWeight forKey:dateString];
}
}
}
// Return only as many date and value dictionaries as requested
// in the method parameters
// The index range starts at the number of total dictionaries we have to return,
// minus how many are requested
// (e.g. 30 total, 4 requested, would be a starting index of 26)
// The index range ends with one less than the number of possible dictionaries to return
// because indexes start at zero
// (e.g. 30 total, minus one = 29, since the indexes for 30 objects are 0-29)
// So this range would include objects at indexes 26, 27, 28, and 29,
// returning 4 values as requested
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(dates.count - numberOfValues, dates.count - 1)];
NSMutableArray *returnDictionaries = [[NSMutableArray alloc] initWithCapacity:indexSet.count];
// Reverse dates so we can work from back to front (most recent to least recent dates)
NSArray *reversedDates = [[dateStrings reverseObjectEnumerator] allObjects];
for (int i = 0; i < indexSet.count; i++) {
NSString *dateString = reversedDates[i];
if ([[datesAndValues valueForKey:dateString] isEqual:@0]) {
// don't include zero values
continue;
}
NSDictionary *jsonDict = [self makeJSONAttributeDict:@"weight"
withData:@{dateString: [datesAndValues valueForKey:dateString]}];
[returnDictionaries addObject:jsonDict];
}
return [returnDictionaries copy];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment