Last active
August 29, 2015 14:16
-
-
Save ankitthakur/6b245f4d836b5ca8ba46 to your computer and use it in GitHub Desktop.
Apple HealthKitUtilities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello, DO you know ho do in OBJ C?