Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - converting from ConstUnsafePointer<()>

Tags:

ios

swift

I'm on beta 3. Consider the following Objective-C line:

const uint8_t *reportData = [data bytes];

where data is a NSData object.

How would this line be re-written in Swift?

data.bytes is of type ConstUnsafePointer<()>, and while there's plenty of documentation on how to create a pointer type in Swift, there isn't much info on how to work with them.

edit: To add some context, I'm trying to port Apple's HeartRateMonitor sample code to Swift. This code interacts with BLE heart rate monitors. This code I'm working on translates the data received by the Bluetooth system into an int for use in the UI. The data received from BT is expected to be an array of uints, element 0 is used to check for a flag and element 1 contains the value.

Here's the same Objective-C line in context:

const uint8_t *reportData = [data bytes];
uint16_t bpm = 0;

if ((reportData[0] & 0x01) == 0) 
{
    /* uint8 bpm */
    bpm = reportData[1];
} 
like image 960
James J Avatar asked Jul 11 '14 00:07

James J


3 Answers

What you were looking for was how to convert NSData to an array of UInt8. Here's how.

import Foundation
let path = "/etc/csh.cshrc" // something existent
let data = NSData(contentsOfFile: path)

var aofb = [UInt8](count:data.length, repeatedValue:0)
data.getBytes(&aofb, length:data.length)

for c in aofb {
    let s = UnicodeScalar(Int(c)).escape(asASCII:true)
    println("\(c):\(s)")
}
like image 77
dankogai Avatar answered Nov 12 '22 16:11

dankogai


Just built following code (Note code below works on Beta 3, ConstUnsafePointer<()> needs to be changed to COpaquePointer in order to work on Beta 2, please see edit history for more information)

var dataPath = NSBundle.mainBundle().pathForResource("TestData", ofType: "") // What I have in TestData is "GREETINGS WORLD"
var originalData = NSData(contentsOfFile: dataPath)
var dataLength = originalData.length
println("original data: \(originalData)") // Output original data

// Data to bytes
var reportBytes: ConstUnsafePointer<()> = originalData.bytes
var bytesToString = NSString(bytes: reportBytes, length: dataLength, encoding: NSUTF8StringEncoding)
println("string from bytes: \(bytesToString)")

// Bytes to data
var bytesToData = NSData(bytes: reportBytes, length: dataLength)
println("data from bytes: \(bytesToData)")

Console log

original data: <47524545 54494e47 5320574f 524c44>
string from bytes: GREETINGS WORLD
data from bytes: <47524545 54494e47 5320574f 524c44>

Also found this may help

ConstUnsafePointer<T>

/// This type stores a pointer to an object of type T. It provides no
/// automated memory management, and therefore the user must take care
/// to allocate and free memory appropriately.

Hope this shed light.

like image 20
vladof81 Avatar answered Nov 12 '22 16:11

vladof81


Looking at handling bluetooth heart rate monitors in Swift now I found the simplest way to get the NSData byte values to UInt8 format:

let bytes = UnsafePointer<UInt8>(data.bytes)

if bytes[0] & 0x01 == 0 {
    NSLog("BPM \(bytes[1]")
}
like image 34
sallyg Avatar answered Nov 12 '22 17:11

sallyg