Skip to content

Instantly share code, notes, and snippets.

@ankitthakur
Last active August 29, 2015 14:16
Show Gist options
  • Select an option

  • Save ankitthakur/6b245f4d836b5ca8ba46 to your computer and use it in GitHub Desktop.

Select an option

Save ankitthakur/6b245f4d836b5ca8ba46 to your computer and use it in GitHub Desktop.
Apple HealthKitUtilities
//
// AppleHealthKitUtilities.swift
// AppleHealthKitPOC
//
// Created by Ankit Thakur on 09/01/15.
// Copyright (c) 2015 Ankit Thakur. All rights reserved
//
import UIKit
import HealthKit
enum HeightQuanityType{
case NotSet
case Millimeters
case Centimeters
case Meters
case Inches
case Feet
}
enum WeightQuanityType{
case NotSet
case Pounds
case Grams
case Kilograms
case Ounce
}
enum BloodType : Int {
case NotSet
case APositive
case ANegative
case BPositive
case BNegative
case ABPositive
case ABNegative
case OPositive
case ONegative
}
let calendarUnit:NSCalendarUnit = .DayCalendarUnit | .YearCalendarUnit | .MonthCalendarUnit | .HourCalendarUnit | .MinuteCalendarUnit | .SecondCalendarUnit | .WeekOfMonthCalendarUnit | .WeekdayCalendarUnit;
protocol Instantiable {
init()
}
let inchesToMeter : Double = 0.0254
class AppleHealthKitUtilities: NSObject {
var healthKitStore = HKHealthStore();
var isPermissionGranted:Bool = false;
// singleton
class var sharedInstance: AppleHealthKitUtilities {
struct Static {
static var instance: AppleHealthKitUtilities?
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = AppleHealthKitUtilities()
Static.instance!.initializForPermissions();
}
return Static.instance!
}
func initializForPermissions(){
healthKitStore.requestAuthorizationToShareTypes(self.requestForSharePermissions() as! Set<NSObject>, readTypes: self.requestForReadPermissions() as! Set<NSObject>) { (success:Bool, error:NSError!) -> Void in
self.isPermissionGranted = success;
NSNotificationCenter.defaultCenter().postNotificationName("permissiongranted", object: nil);
// [[NSNotificationCenter defaultCenter] postNotificationName:@"stopAndPauseMedia" object:nil];
if (!success) {
NSLog("You didn't allow HealthKit to access these read/write data types. In your app, try to handle this error gracefully when a user decides not to provide access. The error was: %@. If you're using a simulator, try it on a device.", error);
}
else{
}
}
}
// request permissions
func requestForPermissions(completion: ((Bool, NSError!) -> Void)!){
healthKitStore.requestAuthorizationToShareTypes(self.requestForSharePermissions() as! Set<NSObject>, readTypes: self.requestForReadPermissions() as! Set<NSObject>) { (success:Bool, error:NSError!) -> Void in
if (!success) {
NSLog("You didn't allow HealthKit to access these read/write data types. In your app, try to handle this error gracefully when a user decides not to provide access. The error was: %@. If you're using a simulator, try it on a device.", error);
}
else{
}
completion(success, error);
}
}
func requestForReadPermissions() -> NSSet {
let bmiQuantityType:HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMassIndex);
let heightQuantityType:HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight);
let stepCountQuantityType:HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount);
let weightQuantityType:HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass);
let birthdayType:HKCharacteristicType = HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierDateOfBirth);
let biologicalSexType:HKCharacteristicType = HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierBiologicalSex);
let workoutType = HKQuantityType.workoutType();
let walkingRunning = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning);
return NSSet(array: [bmiQuantityType, heightQuantityType, stepCountQuantityType, weightQuantityType, birthdayType, biologicalSexType, workoutType, walkingRunning]);
}
func requestForSharePermissions() -> NSSet {
let bmiQuantityType:HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMassIndex);
let heightQuantityType:HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight);
let stepCountQuantityType:HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierStepCount);
let weightQuantityType:HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass);
let workoutType = HKQuantityType.workoutType();
let walkingRunning = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning);
return NSSet(array: [bmiQuantityType, heightQuantityType, stepCountQuantityType, weightQuantityType, workoutType, walkingRunning]);
}
// converters
func convertHeight(heightQuanityType:HeightQuanityType, toHeightQuanityType:HeightQuanityType, value:Double) -> Double{
let currentUnit:HKUnit = self.heightUnit(heightQuanityType);
let toUnit:HKUnit = self.heightUnit(toHeightQuanityType);
let height = HKQuantity(unit: currentUnit, doubleValue: value);
let newHeight = height.doubleValueForUnit(toUnit);
return newHeight;
}
func convertHeight(height:HKQuantity!, toHeightQuanityType:HeightQuanityType!) -> Double{
let toUnit:HKUnit = self.heightUnit(toHeightQuanityType);
let newHeight = height.doubleValueForUnit(toUnit);
return newHeight;
}
func convertWeight(weightQuanityType:WeightQuanityType!, toWeightQuanityType:WeightQuanityType!, value:Double!) -> Double{
if weightQuanityType == .NotSet {
}
let currentUnit:HKUnit = self.weightUnit(weightQuanityType);
let toUnit:HKUnit = self.weightUnit(toWeightQuanityType);
let weight = HKQuantity(unit: currentUnit, doubleValue: value);
let newWeight = weight.doubleValueForUnit(toUnit);
return newWeight;
}
func convertWeight(weight:HKQuantity!, toWeightQuanityType:WeightQuanityType!) -> Double{
let toUnit:HKUnit = self.weightUnit(toWeightQuanityType);
let newWeight = weight.doubleValueForUnit(toUnit);
return newWeight;
}
// units
func heightUnit(heightQuanityType:HeightQuanityType) -> HKUnit{
switch heightQuanityType {
case .Millimeters:
return HKUnit.meterUnitWithMetricPrefix(.Milli)
case .Centimeters:
return HKUnit.meterUnitWithMetricPrefix(.Centi)
case .Inches:
return HKUnit.inchUnit()
case .Feet:
return HKUnit.footUnit()
default: //meters
return HKUnit.meterUnit()
}
}
func weightUnit(weightQuanityType:WeightQuanityType) -> HKUnit{
switch weightQuanityType {
case .Pounds:
return HKUnit.poundUnit()
case .Kilograms:
return HKUnit(fromString:"kg")
case .Ounce:
return HKUnit.ounceUnit()
default: // Grams
return HKUnit.gramUnit()
}
}
// read data
func readDateOfBirthInformation() -> NSDate!{
var dateOfBirth = NSDate();
var dateOfBirthError: NSError?
let birthDate = self.healthKitStore.dateOfBirthWithError(&dateOfBirthError)
as NSDate?
if let error = dateOfBirthError{
println("Could not read user's date of birth")
} else {
if let dob = birthDate{
dateOfBirth = dob;
println("The user DOB is \(dateOfBirth)")
} else {
println("User has not specified her date of birth yet")
}
}
return dateOfBirth;
}
func readAgeInformation() -> Int{
var birthAge = 0;
var dateOfBirthError: NSError?
let birthDate = self.healthKitStore.dateOfBirthWithError(&dateOfBirthError)
as NSDate?
if let error = dateOfBirthError{
println("Could not read user's date of birth")
} else {
if let dateOfBirth = birthDate{
let formatter = NSNumberFormatter()
let now = NSDate()
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate:dateOfBirth, toDate:NSDate(), options:NSCalendarOptions.MatchStrictly)
birthAge = components.year
println("The user is \(birthAge) years old")
} else {
println("User has not specified her date of birth yet")
}
}
return birthAge;
}
func readBiologicalSexInformation() -> GenderType{
var genderType:GenderType = .NotSet;
var biologicalSexError: NSError?
var biologicalSexObject:HKBiologicalSexObject? = self.healthKitStore.biologicalSexWithError(&biologicalSexError);
if let error = biologicalSexError{
println("Could not read user's date of birth")
} else {
println("The user gender is \(biologicalSexObject?.biologicalSex)")
switch biologicalSexObject!.biologicalSex {
case .Female:
genderType = .Female;
break
case .Male:
genderType = .Male;
break
default:
genderType = .NotSet;
break
}
}
return genderType;
}
func readBloodGroupTypeInformation() -> BloodType{
var bloodType:BloodType = .NotSet;
var bloodTypeError: NSError?
var bloodTypeObject:HKBloodTypeObject? = self.healthKitStore.bloodTypeWithError(&bloodTypeError);
if let error = bloodTypeError{
println("Could not read user's date of birth")
} else {
switch bloodTypeObject!.bloodType {
case .NotSet:
bloodType = .NotSet;
break
case .APositive:
bloodType = .APositive;
break
case .ANegative:
bloodType = .ANegative;
break
case .BPositive:
bloodType = .BPositive;
break
case .BNegative:
bloodType = .BNegative;
break
case .ABPositive:
bloodType = .ABPositive;
break
case .ABNegative:
bloodType = .ABNegative;
break
case .OPositive:
bloodType = .OPositive;
break
case .ONegative:
bloodType = .ONegative;
break
}
}
return bloodType;
}
func readUserHeightInUnits(unit:HeightQuanityType, completion: ((Double!, NSError?) -> Void)!) ->Void{
let sampleType = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight)
self.readMostRecentSample(sampleType, completion: {(quantitySample:HKSample!, error:NSError!) -> Void in
var userHeight:Double = 0;
var height:HKQuantitySample?;
if(error != nil)
{
println("Error reading weight from HealthKit Store: \(error.localizedDescription)")
}
else{
height = quantitySample as? HKQuantitySample;
if let quantity = height?.quantity {
userHeight = self.convertHeight(quantity, toHeightQuanityType: unit);
println("The user height is \(userHeight)")
}
}
completion(userHeight, error);
});
}
func readUserWeightInUnits(unit:WeightQuanityType, completion: ((Double!, NSError?) -> Void)!) ->Void{
let sampleType = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass)
self.readMostRecentSample(sampleType, completion: {(quantitySample:HKSample!, error:NSError!) -> Void in
var userWeight:Double = 0;
var weight:HKQuantitySample?;
if(error != nil)
{
println("Error reading weight from HealthKit Store: \(error.localizedDescription)")
}
else{
weight = quantitySample as? HKQuantitySample;
if let quantity = weight?.quantity {
userWeight = self.convertWeight(quantity, toWeightQuanityType: unit);
println("The user weight is \(userWeight)")
}
}
completion(userWeight, error);
});
}
func readMostRecentSample(sampleType:HKSampleType , completion: ((HKSample!, NSError!) -> Void)!)
{
// 1. Build the Predicate
let past = NSDate.distantPast() as! NSDate
let now = NSDate()
let mostRecentPredicate = HKQuery.predicateForSamplesWithStartDate(past, endDate:now, options: .None)
// Build the sort descriptor to return the samples in descending order
let sortDescriptor = NSSortDescriptor(key:HKSampleSortIdentifierEndDate, ascending: false)
// we want to limit the number of samples returned by the query to just 1 (the most recent)
let limit = 1
// Build samples query
let sampleQuery = HKSampleQuery(sampleType: sampleType, predicate: nil, limit: limit, sortDescriptors: [sortDescriptor])
{ (sampleQuery, results, error ) -> Void in
if let queryError = error {
completion(nil,error)
return;
}
// Get the first sample
let mostRecentSample = results.first as? HKQuantitySample
// Execute the completion closure
if completion != nil {
completion(mostRecentSample,nil)
}
}
// Execute the Query
self.healthKitStore.executeQuery(sampleQuery)
}
override class func automaticallyNotifiesObserversForKey(key: String) -> Bool{
return true;
}
func saveHeightSample(heightInInch:Double, withCompletion completion: ((Bool, NSError!) -> Void)!){
// inches to meter conversion
let heightInMeter : Double = heightInInch * inchesToMeter
let meterUnit:HKUnit = HKUnit.meterUnit();
let heightQuantity = HKQuantity(unit: meterUnit, doubleValue: Double(heightInMeter))
let heightType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight)
let now = NSDate()
let heightSample = HKQuantitySample(type: heightType, quantity: heightQuantity, startDate: now, endDate: now)
self.healthKitStore.saveObject(heightSample, withCompletion: { (success : Bool, error : NSError!) -> Void in
if(!success)
{
NSLog("An error occured saving the height sample %@. In your app, try to handle this gracefully. The error was: %@.", heightSample, error)
} else {
println("Height sample saved successfully!!!")
}
completion(success, error);
})
}
func saveWeightSample(weightInGrams:Double, withCompletion completion: ((Bool, NSError!) -> Void)!){
// inches to meter conversion
var gramUnit:HKUnit = HKUnit.gramUnit();
let weightQuantity = HKQuantity(unit: gramUnit, doubleValue: Double(weightInGrams))
let weightType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass)
let now = NSDate()
let weightSample = HKQuantitySample(type: weightType, quantity: weightQuantity, startDate: now, endDate: now)
self.healthKitStore.saveObject(weightSample, withCompletion: { (success : Bool, error : NSError!) -> Void in
if(!success)
{
NSLog("An error occured saving the weight sample %@. In your app, try to handle this gracefully. The error was: %@.", weightSample, error)
} else {
println("Weight sample saved successfully!!!")
}
completion(success, error);
})
}
func saveBMISample(bmi:Double, withCompletion completion: ((Bool, NSError!) -> Void)!){
// 1. Create a BMI Sample
let bmiType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMassIndex)
let bmiQuantity = HKQuantity(unit: HKUnit.countUnit(), doubleValue: bmi)
let now = NSDate()
let bmiSample = HKQuantitySample(type: bmiType, quantity: bmiQuantity, startDate:now, endDate: now)
// 2. Save the sample in the store
healthKitStore.saveObject(bmiSample, withCompletion: { (success, error) -> Void in
if( error != nil ) {
println("Error saving BMI sample: \(error.localizedDescription)")
} else {
println("BMI sample saved successfully!!!")
}
completion(success, error);
})
}
func readRunningWorkOuts(completion: (([AnyObject]!, NSError!) -> Void)!){
// 1. Predicate to read only running workouts
let predicate = HKQuery.predicateForWorkoutsWithWorkoutActivityType(HKWorkoutActivityType.Running)
// 2. Order the workouts by date
let sortDescriptor = NSSortDescriptor(key:HKSampleSortIdentifierStartDate, ascending: false)
// 3. Create the query
let sampleQuery = HKSampleQuery(sampleType: HKWorkoutType.workoutType(), predicate: predicate, limit: 0, sortDescriptors: [sortDescriptor])
{ (sampleQuery, results, error ) -> Void in
var workouts:Array<HKWorkoutModel> = [];
if let queryError = error {
println( "There was an error while reading the samples: \(queryError.localizedDescription)")
}
else{
// println("============================");
// println("reading workouts: \(results)");
// println("============================");
for object in results{
let wObject:HKWorkout = object as! HKWorkout;
var workout:HKWorkoutModel = HKWorkoutModel(workout: wObject);
workouts.append(workout);
}
}
completion(workouts, error)
}
// 4. Execute the query
healthKitStore.executeQuery(sampleQuery)
}
func groupByDays(routeModels: Array<HKWorkoutModel>) -> [WorkoutEntry] {
var result:[WorkoutEntry] = [] // array of <monthIndex, array of routemodels>
let formatter = NSNumberFormatter()
let now = NSDate();
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now)
let currentWeek = components.weekday;
let currentDay = components.day;
let currentMonth = components.month;
var dayArray:[Int] = [];
for (var index:Int = 0; index < currentDay; index++){
dayArray.append(index+1);
}
var dayRecords:Array<HKWorkoutModel> = [];
// get array on days
for routeModel in routeModels {
let formatter = NSNumberFormatter()
let now = (routeModel as HKWorkoutModel).workoutStartTime!;
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now)
let day:Int = components.day;
let month:Int = components.month;
if(month == currentMonth){
if !contains(dayArray, day){
dayArray.append(day);
}
}
}
// looping on days
for m in dayArray {
let dayIndex = m;
var workoutRouteModels :Array<HKWorkoutModel> = [];
//grouping array of records by current day (m).
for record in routeModels {
let formatter = NSNumberFormatter()
let now = (record as HKWorkoutModel).workoutStartTime!;
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now);
let day = components.day;
if day == dayIndex {
workoutRouteModels.append(record);
}
}
var entry:WorkoutEntry = (dayIndex, workoutRouteModels);
result.append(entry);
}
result.sort { (workoutEntry1: WorkoutEntry, workoutEntry2: WorkoutEntry) -> Bool in
return (workoutEntry1.index < workoutEntry2.index)
};
return result
}
func groupActivitiesByDays(routeModels: Array<HKWorkoutModel>) -> [WorkoutEntry] {
var result:[WorkoutEntry] = [] // array of <monthIndex, array of routemodels>
let formatter = NSNumberFormatter()
let now = NSDate();
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now)
let currentWeek = components.weekday;
let currentDay = components.day;
let currentMonth = components.month;
let initialDay = currentDay-7;
var dayArray:[Int] = [1,2,3,4,5,6,7];
var dayRecords:Array<HKWorkoutModel> = [];
// looping on days
for m in dayArray {
let dayIndex = m;
var workoutRouteModels :Array<HKWorkoutModel> = [];
var routemodels:Array<HKWorkoutModel> = routeModels;
routemodels.sort { (routeModel1: HKWorkoutModel, routeModel2: HKWorkoutModel) -> Bool in
return (routeModel1.workoutStartTime!.timeIntervalSince1970 < routeModel2.workoutStartTime!.timeIntervalSince1970)
};
//grouping array of records by current day (m).
for record in routemodels {
let formatter = NSNumberFormatter()
let now = (record as HKWorkoutModel).workoutStartTime!;
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now);
var day = components.day;
day = currentDay - day;
if day == dayIndex {
workoutRouteModels.append(record);
}
}
var entry:WorkoutEntry = (dayIndex, workoutRouteModels);
result.append(entry);
}
return result
}
func groupWeekDataByDays(routeModels: Array<HKWorkoutModel>) -> [WorkoutEntry] {
var result:[WorkoutEntry] = [] // array of <monthIndex, array of routemodels>
let formatter = NSNumberFormatter()
let now = NSDate();
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now)
let currentWeek = components.weekday;
var dayArray:[Int] = [1,2,3,4,5,6,7];
var dayRecords:Array<HKWorkoutModel> = [];
// looping on days
for m in dayArray {
let dayIndex = m;
var workoutRouteModels :Array<HKWorkoutModel> = [];
var routemodels:Array<HKWorkoutModel> = routeModels;
routemodels.sort { (routeModel1: HKWorkoutModel, routeModel2: HKWorkoutModel) -> Bool in
return (routeModel1.workoutStartTime!.timeIntervalSince1970 < routeModel2.workoutStartTime!.timeIntervalSince1970)
};
//grouping array of records by current day (m).
for record in routemodels {
let formatter = NSNumberFormatter()
let now = (record as HKWorkoutModel).workoutStartTime!;
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now);
let day = components.weekday;
if day == dayIndex {
workoutRouteModels.append(record);
}
}
var entry:WorkoutEntry = (dayIndex, workoutRouteModels);
result.append(entry);
}
return result
}
func groupMonthDataByWeeks(routeModels: Array<HKWorkoutModel>) -> [WorkoutEntry] {
var result:[WorkoutEntry] = [] // array of <monthIndex, array of routemodels>
let formatter = NSNumberFormatter()
let now = NSDate();
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now)
let currentMonth = components.month;
var weekArray:[Int] = [1,2,3,4,5,6,7];
var weekRecords:Array<HKWorkoutModel> = [];
// looping on days
for m in weekArray {
let monthIndex = m;
var workoutRouteModels :Array<HKWorkoutModel> = [];
var routemodels:Array<HKWorkoutModel> = routeModels;
routemodels.sort { (routeModel1: HKWorkoutModel, routeModel2: HKWorkoutModel) -> Bool in
return (routeModel1.workoutStartTime!.timeIntervalSince1970 < routeModel2.workoutStartTime!.timeIntervalSince1970)
};
//grouping array of records by current week (m).
for record in routemodels {
let formatter = NSNumberFormatter()
let now = (record as HKWorkoutModel).workoutStartTime!;
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now);
let month = components.month;
if month == monthIndex {
workoutRouteModels.append(record);
}
}
var entry:WorkoutEntry = (monthIndex, workoutRouteModels);
result.append(entry);
}
return result
}
func groupByWeek(routeModels: Array<HKWorkoutModel>) -> [WorkoutEntry] {
var result:Array<WorkoutEntry> = [] // array of <monthIndex, array of routemodels>
let formatter = NSNumberFormatter()
let now = NSDate();
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now);
let currentWeek = components.weekOfMonth;
let currentMonth = components.month;
var weekArray:[Int] = [];
var weekRecords:Array<HKWorkoutModel> = [];
for routeModel in routeModels {
let formatter = NSNumberFormatter()
let now = (routeModel as HKWorkoutModel).workoutStartTime!;
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now)
println(components);
let week = components.weekOfMonth;
let month = components.month;
if(month == currentMonth){
if !contains(weekArray, week){
weekArray.append(week);
}
}
}
// looping on weeks
for m in weekArray {
let weekIndex = m;
var workoutRouteModels :Array<HKWorkoutModel> = [];
//grouping array of records by current week (m).
// var routemodels:Array<HKWorkoutModel> = routeModels;
//
// routemodels.sort { (routeModel1: HKWorkoutModel, routeModel2: HKWorkoutModel) -> Bool in
// return (routeModel1.workoutStartTime!.timeIntervalSince1970 < routeModel2.workoutStartTime!.timeIntervalSince1970)
// };
for record in routeModels {
let formatter = NSNumberFormatter()
let now = (record as HKWorkoutModel).workoutStartTime!;
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now);
let week = components.weekOfMonth;
if week == weekIndex {
workoutRouteModels.append(record);
}
}
var entry:WorkoutEntry = (weekIndex, workoutRouteModels);
result.append(entry);
}
return result
}
func groupByMonthAndYear(routeModels: [HKWorkoutModel]) -> [WorkoutEntry] {
var result:[WorkoutEntry] = [] // array of <monthIndex, array of routemodels>
let formatter = NSNumberFormatter()
let now = NSDate();
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now);
let currentMonth = components.month;
let currentYear = components.year;
var monthArray:[Int] = [];
var monthRecords:Array<HKWorkoutModel> = [];
var routemodels:Array<HKWorkoutModel> = routeModels;
routemodels.sort { (routeModel1: HKWorkoutModel, routeModel2: HKWorkoutModel) -> Bool in
return (routeModel1.workoutStartTime!.timeIntervalSince1970 < routeModel2.workoutStartTime!.timeIntervalSince1970)
};
// get array on months
for routeModel in routemodels {
let formatter = NSNumberFormatter()
let now = (routeModel as HKWorkoutModel).workoutStartTime!;
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now);
let month = components.month;
let year = components.year;
if(year == currentYear){
if !contains(monthArray, month){
monthArray.append(month);
}
}
}
// looping on months
for m in monthArray {
let monthIndex = m;
var workoutRouteModels :[HKWorkoutModel] = [];
//grouping array of records by current month (m).
for record in routeModels {
let formatter = NSNumberFormatter()
let now = (record as HKWorkoutModel).workoutStartTime!;
let components = NSCalendar.currentCalendar().components(calendarUnit, fromDate: now);
let month = components.month;
if month == monthIndex {
workoutRouteModels.append(record);
}
}
var entry:WorkoutEntry = (monthIndex, workoutRouteModels);
result.append(entry);
}
return result
}
}
@faganello60

Copy link
Copy Markdown

Hello, DO you know ho do in OBJ C?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment