It seems like it should be simple enough, but try to confirm what you are saying. Does "bytes" mean "16447d03"? This is a pointer to the data, not the data itself, so you need to do something like this to get the actual value:
var data = characteristic.value var values = [UInt8](count:data.length, repeatedValue:0) data.getBytes(&values, length:data.length)
In this "values" are an array containing the actual values.
From the private discussion that we had, you indicated the result as:
[22, 77, 22, 3] [22, 78, 27, 3, 18, 3] [22, 79, 2, 3] [22, 78, 15, 3]
The first byte is the flags, which were 22 in all cases that you specified. This makes sense, like everything else, from the same heart rate equipment.
Bits are grouped as follows: | 3 bits reserved | 1 bit for RR interval | 1 bit for power consumption | 2 bits for sensor contact status | 1 bit for heart rate format | 22 - 00010110 in binary format, which is equal to | 000 | 1 | 0 | 11 | 0 |.
Bit rate format: 0 (Heart rate value format is set to UINT8)
Sensor contact status values: 3 (sensor contact function is supported and a contact is detected)
Energy Consumption of status bits: 0 (Energy Field not considered)
RR-Interval bit: 1 (one or more RR-Interval values ββpresent)
This means that the next byte is the heart rate (field C1), and the remaining bytes are the RR-Interval values, regardless of what they are (field C4).
Thus, for these data, the heart rate was 77, 78, 79, 78.