Last active
December 10, 2016 22:21
-
-
Save indisoluble/60f564ec96fc958f22801dcaac9bbad1 to your computer and use it in GitHub Desktop.
Simple VC to retrieve all heart rate records in an iPhone and store them in CSV files
This file contains hidden or 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
/* | |
Steps: | |
1. Create a new project using template: 'Single View Application'. | |
2. Enable HealthKit capabilities for the app. | |
3. Add these properties to 'Info.plist': | |
- 'NSHealthShareUsageDescription' | |
- 'NSHealthUpdateUsageDescription' | |
4. Copy & paste the content of this file into 'ViewController.swift'. | |
4. Run the app in your iPhone. | |
5. Using Xcode, download the container for this app. | |
6. Open the container. Inside folder 'Documents', there is a bunch of CSV | |
files with all your heart rate records until the current moment. Each | |
file is suffixed with the date of the records inside. Each record is a | |
tuple with the following format: | |
<Time when the record was saved>,<Heart rate in bpm> | |
NOTICE: The timezone for all records is GMT. | |
*/ | |
import HealthKit | |
import UIKit | |
class ViewController: UIViewController { | |
let healthStore = HKHealthStore() | |
let heartRateType = HKObjectType.quantityType(forIdentifier: .heartRate)! | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
if !HKHealthStore.isHealthDataAvailable() { | |
print("Health data is NOT available") | |
return | |
} | |
healthStore.requestAuthorization(toShare: nil, | |
read: [heartRateType], | |
completion: { [weak self] (success, error) in | |
guard success else { | |
print("Request auth. Error:", error!) | |
return | |
} | |
print("Autherization granted") | |
self?.queryHeartRateSamples() | |
}) | |
} | |
func queryHeartRateSamples() { | |
let predicate = HKQuery.predicateForSamples(withStart: Date(timeIntervalSince1970: 0), | |
end: Date()) | |
let query = HKSampleQuery(sampleType: heartRateType, | |
predicate: predicate, | |
limit: HKObjectQueryNoLimit, | |
sortDescriptors: nil, | |
resultsHandler: { [weak self] (_, results, error) in | |
guard results != nil else { | |
print("Query. Error:", error!) | |
return | |
} | |
print("Samples retrieved") | |
self?.processHeartRateSamples(results as! [HKQuantitySample]) | |
}) | |
healthStore.execute(query) | |
} | |
func processHeartRateSamples(_ heartRateSamples: [HKQuantitySample]) { | |
let gmtZone = TimeZone(abbreviation: "GMT")! | |
var calendar = Calendar(identifier: .gregorian) | |
calendar.timeZone = gmtZone | |
let formatter = DateFormatter() | |
formatter.timeZone = gmtZone | |
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" | |
var csv: FileHandle? | |
var csvDate = Date(timeIntervalSince1970: 0) | |
for sample in heartRateSamples { | |
let order = calendar.compare(sample.startDate, to: csvDate, toGranularity: .day) | |
if order != ComparisonResult.orderedSame { | |
csv?.closeFile() | |
csvDate = sample.startDate | |
let csvURL = csvFileURLWithDate(csvDate) | |
print("Build \(csvURL.lastPathComponent)") | |
try? "Time,BPM\n".write(to: csvURL, atomically: false, encoding: .utf8) | |
csv = try? FileHandle(forWritingTo: csvURL) | |
csv?.seekToEndOfFile() | |
} | |
let date = sample.startDate | |
let heartRate = sample.quantity.doubleValue(for: HKUnit(from: "count/min")) | |
csv?.write("\(formatter.string(from: date)),\(heartRate)\n".data(using: .utf8)!) | |
} | |
csv?.closeFile() | |
print("Done") | |
} | |
func csvFileURLWithDate(_ date: Date) -> URL { | |
let dirs = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) | |
let docURL = URL(fileURLWithPath: dirs.first!) | |
let dateFormatter = DateFormatter() | |
dateFormatter.dateFormat = "yyyyMMdd" | |
let filename = "heartRate-\(dateFormatter.string(from: date)).csv" | |
return URL(fileURLWithPath: filename, relativeTo: docURL) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment