Sending a PNG image with BLE in Swift

1.2k Views Asked by At

I've been stuck with this problem for the past 2 hours and I'm about to give up. I've Googled a lot and just can't find something that works. I am using the newest version of XCode.

I want to send a PNG image through Bluetooth Low Energy, the receiver in this case is Bleno. Things I've tried include converting the image to a Base64 String and converting the image to an UInt8 array and sending each entry in the array one by one.

Nothing I do works, so the only "working" code I is for converting an image to bytes, which is this:

let testImage = UIImage(named: "smallImage")
let imageData = UIImagePNGRepresentation(testImage!)

I already have all the connection code for BLE and am able to send a simple and short string successfully to Bleno. I also know through "peripheral.maximumWriteValueLength" that the maximum amount of bytes I can send at once is 512 bytes, although I can imagine that using Low Energy lowers this maximum. I'm trying to send the data with peripheral.writeValue, which looks like this at the moment (array was the UInt8 array I tried):

peripheral.writeValue(Data(bytes:array), for: char, type: CBCharacteristicWriteType.withResponse)

The error I most often get is Error Domain=CBATTErrorDomain Code=13 "The value's length is invalid.", which I assume is because the data I try to send is more than 512 bytes. I tried sending the data in packages smaller than 512 bytes, but like I said, I just can't get it to work.

In short my question is this: How do I send a PNG image (in multiple parts) through BLE?

Edit: I'm got something to work, altough it is pretty slow, because it's not utilising the full 20 bytes per packet:

let buffer: [UInt8] = Array(UIImagePNGRepresentation(testImage!)!)

            let start = "I:"+String(buffer.count)
            peripheral.writeValue(start.data(using: .utf8)!, for: char, type: CBCharacteristicWriteType.withResponse)

            buffer.forEach{b in
                let data = NSData(bytes: [UInt8(b)], length: MemoryLayout<UInt8>.size)
                peripheral.writeValue(data as Data, for: char, type: CBCharacteristicWriteType.withResponse)
            }

Thanks in advance!

0

There are 0 best solutions below