Search code examples
ioscore-bluetoothcbcentralmanagercbperipheral

Improve file transfer speed using CoreBluetooth


I currently have my OSX app (central) sending a 4Kb image to my iOS app (peripheral) trough a writeable characteristic using writeValue.

Because the image size exceeds the limit, I'm using writeValue multiple times with the following function:

func sendData() {
    while (self.sendDataIndex < self.dataToSend.length) {
        var amountToSend = self.dataToSend.length - self.sendDataIndex!

        if (amountToSend > NOTIFY_MTU) {
            amountToSend = NOTIFY_MTU
        }

        // Copy out the data we want
        var chunk = self.dataToSend.subdataWithRange(NSMakeRange(self.sendDataIndex!, amountToSend))

        // Send it
        self.discoveredPeripheral?.writeValue(chunk, forCharacteristic: self.setupCharacteristic, type: CBCharacteristicWriteType.WithoutResponse)

        // It did send, so update our index
        self.sendDataIndex = self.sendDataIndex!+amountToSend;

    }
    self.discoveredPeripheral?.writeValue("EOM".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true), forCharacteristic: self.setupCharacteristic, type: CBCharacteristicWriteType.WithResponse)
}

My problem is that it takes much longer than I need it to, approximately 30 seconds.

The weird thing is, even though I use CBCharacteristicWriteType.WithoutResponse when sending the image, I get responses for them, I wonder whether that's making it slow.

This is how I have my characteristic setup on the peripheral side:

var cbProperties = CBCharacteristicProperties.Read|CBCharacteristicProperties.Write|CBCharacteristicProperties.Notify
var cbPermissions = CBAttributePermissions.Readable|CBAttributePermissions.Writeable
var transferCharacteristic = CBMutableCharacteristic(type: CBUUID.UUIDWithString(SETUP_CHARACTERISTIC_UUID), properties: cbProperties, value: nil, permissions: cbPermissions)

I've tried different values for NOTIFY_MTU, ranging from 20 to 900, but the higher it is, the fewer times writeValue is executed, but the longer each package takes to arrive.

I've seen transfers perform much faster, any suggestions on how to improve it?

Thanks


Solution

  • I was able to bring it down to 3 seconds by changing CBCharacteristicProperties to WriteWithoutResponse.

    Packages are transferred insanely faster but I lost the response to know when they were delivered, so I had to implement my own response to know when the transfer has finished.

    Other than that it's working great!