1

First, I am coming from a C programming background. My system consists of a device that is using software written in C language which utilizes Bluetooth to talk to the iPhone Application. I have a struct defined on the C device that I send byte by byte through Bluetooth and I am trying to reconstruct the struct in Swift.

In C, I would use a pointer to the array of bytes and simply typecast it to a pointer of my custom struct type:

uint8_t arrayOfBytes[16];

CustomStructType_t * structPtr = (CustomStructType_t *)arrayOfBytes;

In C, this is simple. I had an array of bytes, but I used typecasting to represent it as a custom struct instead.

Now on the iPhone, I capture the incoming Bluetooth bytes using Core Bluetooth. When a characteristic is updated, the following line accepts the bluetooth packet and converts it from Data type to String of bytes.

let incomingByteString = String(data: receivedBluetoothDataPacket, encoding: String.Encoding.utf8)

I'm honestly super lost at this point. I want to use this packet to initialize, or update the values of a struct object, lets say:

struct CustomStruct {
  let name: String!
  let value: Int
}

It would be nice if I could just tell Swift, Hey, I want you to create a CustomStruct object out of this incomingByteString.

Looks like this is going to be a real pain, and I may need to format the incoming packet much differently to accommodate Swift. Any advice is appreciated.

3
  • From this 16 bytes, what range are name: String and value: Int? For example do you now that first 10 bytes is name and the rest is value or it's dynamic? Commented Jun 3, 2020 at 6:49
  • This probably will help you: stackoverflow.com/questions/28916535/… Commented Jun 3, 2020 at 6:51
  • @vpoltave You've already identified a key problem I need to resolve. The answer to your question is Yes, I do know precisely how many bytes are allocated for each member of the struct. However, the number of bytes allocated are defined on the C device. When it comes to swift I am not sure how to ensure that a struct member of type String is of size 10 bytes, for example. I need to be sure that in Swift, each member takes up a defined amount of bytes in memory, otherwise a simple byte pointer conversion would not work. Commented Jun 6, 2020 at 15:53

1 Answer 1

1

Try this

let bytes: [UInt8] = //get your bytes here
let customStruct = bytes.withUnsafeBufferPointer {
    ($0.baseAddress!.withMemoryRebound(to: CustomStruct.self, capacity: 1) { $0 })
}.pointee

You would have to convert your receivedBluetoothDataPacket to [UInt8] and you haven't provided the exact type.

Assuming it's Data a simple [UInt8](receivedBluetoothDataPacket) should suffice.

Sign up to request clarification or add additional context in comments.

2 Comments

This is really helpful, but there appears to be a major problem if I wanted to include a String in the Struct. I know that the string would be a maximum of 16 bytes, but Swift does not appear to have a way of specifying strength length. So the block of memory that Swift creates for a struct does not seem to be contiguous and a simple byte copy using the starting address of the struct would fail.
I think your best shot would be 16 variables of Int8 size and some struct method/computed property to finally yield it as a proper Swift String.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.