I am querying heart rate samples taken during a workout. For all of the mentioned cases below I'm wearing an Apple Watch and using the stock Workouts.app in the watch.
If I query heart rate samples for a recent workout, it being yesterday or the past month for example, I get the full samples. If I query a workout let's say, two/three months in the past the samples I get back look "choppy" with a lot of missing data. (See attached image)
imgur.com/a/FbMSBoa
How am I getting the heart rate samples?
swift
extension HKHealthStore: HKHealthStoreCombine {
public func getT(sample: T, start: Date, end: Date, limit: Int = HKObjectQueryNoLimit) - AnyPublisher[HKQuantitySample], Error where T: HKObjectType {
let subject = PassthroughSubject[HKQuantitySample], Error()
let sampleType = HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier(rawValue: sample.identifier))!
let predicate = HKQuery.predicateForSamples(withStart: start, end: end)
let query = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: limit, sortDescriptors: nil, resultsHandler: { (query, samples, error) in
guard error == nil else {
logger.error("Error fetching samples of type \(sample.description) from \(start) to \(end) with a limit of \(limit): \(error!.localizedDescription)")
subject.send(completion: .failure(error!))
return
}
let samples = samples as? [HKQuantitySample] ?? []
logger.log("Successfully fetched \(samples.count) samples of type \(sample.description) from \(start) to \(end) with a limit of \(limit)")
subject.send(samples)
subject.send(completion: .finished)
})
self.execute(query)
return subject.eraseToAnyPublisher()
}
}
swift
healthStore.get(sample: HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!, start: workout.startDate, end: workout.endDate)
.map({
$0.compactMap({ $0.quantity.doubleValue(for: UserUnits.shared().heartCountUnits) })
})
.replaceError(with: [])
.receive(on: DispatchQueue.main)
.sink(receiveValue: {
self.heartRate = $0
})
.store(in: &bag)
Is this some kind of wrong way that I am working with HealthKit? I don't know what the issue can be but it looks like accessing heart samples in the "past" are somewhat archived and I don't get the full resolution.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am trying to send a simple JSON to a connected Bluetooth peripheral but getting some problems in the process.The properties read from the peripheral in the didDiscoverCharacteristicsFor method are the following:po characteristic.properties
▿ CBCharacteristicProperties
- rawValue : 10Which as this is a mask and if I am not mistaken this states that I can read (2) and write (8) from/to the device.I am writing the data as soon as I discover a new characteristic that matches the requirements in the following wayfunc peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService,error: Error?) {
for characteristic in service.characteristics! {
let characteristic = characteristic as CBCharacteristic
print(characteristic.uuid)
if characteristic.uuid.isEqual(RX_UUID) {
// Received only support for writing with response, writing without response is not allowed
if characteristic.properties.contains(CBCharacteristicProperties.write) {
self.writeJsonStringToPeripheral(peripheral: peripheral, characteristic: characteristic, writeType: .withResponse)
} else if characteristic.properties.contains(CBCharacteristicProperties.writeWithoutResponse) {
self.writeJsonStringToPeripheral(peripheral: peripheral, characteristic: characteristic, writeType: .withoutResponse)
}
}
}
}
func writeJsonStringToPeripheral(peripheral: CBPeripheral, characteristic: CBCharacteristic, writeType: CBCharacteristicWriteType) {
do {
let msgDictionary = ["SSID": self.wiFiCredentials.SSID, "Password": self.wiFiCredentials.Password]
let jsonData = try JSONSerialization.data(withJSONObject: msgDictionary, options: [])
//let data = "".data(using: .utf8)
peripheral.writeValue(jsonData, for: characteristic, type: writeType)
} catch let error as NSError {
debugPrint("Error in auth message JSON: \(error.description)")
This snippet calls the function at line 10 indicating the possibility of writing with a response and after callign it the didWriteValueFor delegate method is called.func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
if let error = error {
print(error)
} else {
print("Value writen sucessfully.")
}
}Printing the following error.Error Domain=CBATTErrorDomain Code=3 "Writing is not permitted." UserInfo={NSLocalizedDescription=Writing is not permitted.}I've made myself sure that the device is connected and I can also see it in the Settings.app. I am a bit lost and I don't know what could be going on here.On the other side if I force the writing to be withoutResponse I get another console log2020-03-25 22:23:50.286662+0100 Cloudy[2595:1232291] [CoreBluetooth] WARNING: Characteristic does not specify the "Write Without Response" property - ignoring response-less writeAfter sending the specified JSON to the device it should start a sequence to connect to the specified WiFi SSID. I am sure the hardware works because I can set those values using the console on the device itself and the process works so there must be something I am missing here that causes this to fail.This test has been done using an iPhone 6S running ios 13.3.1.