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.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
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.