Question or problem in the Swift programming language:
I have recently found a source code in swift and I am trying to get it to objective-C. The one thing I was unable to understand is this:
var theData:UInt8! theData = 3; NSData(bytes: [theData] as [UInt8], length: 1)
Can anybody help me with the Obj-C equivalent?
Just to give you some context, I need to send UInt8 to a CoreBluetooth peripheral (CBPeripheral) as UInt8. Float or integer won’t work because the data type would be too big.
How to solve the problem:
Solution 1:
If you write the Swift code slightly simpler as
var theData : UInt8 = 3 let data = NSData(bytes: &theData, length: 1)
then it is relatively straight-forward to translate that to Objective-C:
uint8_t theData = 3; NSData *data = [NSData dataWithBytes:&theData length:1];
For multiple bytes you would use an array
var theData : [UInt8] = [ 3, 4, 5 ] let data = NSData(bytes: &theData, length: theData.count)
which translates to Objective-C as
uint8_t theData[] = { 3, 4, 5 }; NSData *data = [NSData dataWithBytes:&theData length:sizeof(theData)];
(and you can omit the address-of operator in the last statement,
see for example How come an array’s address is equal to its value in C?).
Solution 2:
In Swift 3
var myValue: UInt8 = 3 // This can't be let properties let value = Data(bytes: &myValue, count: MemoryLayout.size)
Solution 3:
In Swift,
Data
has a native init
method.
// Foundation -> Data /// Creates a new instance of a collection containing the elements of a /// sequence. /// /// - Parameter elements: The sequence of elements for the new collection. /// `elements` must be finite. @inlinable public init(_ elements: S) where S : Sequence, S.Element == UInt8 @available(swift 4.2) @available(swift, deprecated: 5, message: "use `init(_:)` instead") public init(bytes elements: S) where S : Sequence, S.Element == UInt8
So, the following will work.
let values: [UInt8] = [1, 2, 3, 4] let data = Data(values)