I am running iOS 10 beta 2. I have noticed that you will now get a peripheral:didWriteValueForCharacteristic:error: callback even when using characteristic write commands (CBCharacteristicWriteWithoutResponse). Previously you would only get this when using write requests (CBCharacteristicWriteWithResponse).. This, to me, is not an improvement to the API, but rather makes it worse.
First of all, it is a bit counter intuitive to get a confirmation that you have written data when there is no guarantee that the data will arrive on the other side, or even be sent in the first place. At first I thought that this callback was added as a confirmation that at least the bluetooth stack has received the message, but that does not appear to be the case. If that had been the case, then you could have used it as sort of like a "flow control" mechanism (like you can on Android) to avoid packets being lost due to buffer limitations in the bluetooth stack. I did however test this and when sending data at a rapid pace, with each new packet being sent in the callback of the previous one, the bluetooth stack starts to discard packets after around 30 packets with 20 bytes payload. This appears to be the same as if you just add the packets in a loop directly. So, my point here is that I do not understand why this feature was added?
Second, I believe that this API breaking change could generate a lot of unsuspected bugs in applications that have presumed that you would not get this callback. In the current documentation on Apple's website for the writeValue:forCharacteristic:type: method it explicitly says:
When you call this method to write the value of a characteristic, the peripheral calls the
peripheral:didWriteValueForCharacteristic:error: method of its delegate object only if you
specified the write type as CBCharacteristicWriteWithResponse.Additionally, for the documentation of peripheral:didWriteValueForCharacteristic:error: it says:
This method is invoked only when your app calls the writeValue:forCharacteristic:type: method with the
CBCharacteristicWriteWithResponse constant specified as the write type.And lastly I can add that in the CBPeripheral.h header file of the latest iOS 10 beta it still states something similar (although in different words):
If the CBCharacteristicWriteWithResponse type is specified,
peripheral:didWriteValueForCharacteristic:error: is called with the result of the write request.and
This method returns the result of a writeValue:forCharacteristic:type: call,
when the CBCharacteristicWriteWithResponse type is used.Any comments on this?
/Anton