4 Replies
Latest reply on Oct 12, 2016 3:58 AM by aranel_rauta  Level 1 (0 points)

Here is my Swift 2 code to extract a ble charcteristic value:

var ts:UInt16 = 0

var tsData = characteristic.value

print("         timeStamp value: \(characteristic.value)")

let count = tsData!.length / sizeof(UInt32)

var array = [UInt32](count: count, repeatedValue: 0)

tsData!.getBytes(&array, length: count * sizeof(UInt32))

// Swap each integer:

for i in 0 ..< count {

array[i] = array[i].byteSwapped

}

let timestampHex = NSData(bytes: &array, length: count*sizeof(UInt32))

print("         timestampHex value: \(timestampHex)")

timeStamp value: Optional(<31000000>)

timestampHex value: <00000031>

I need to convert the timestampHex value to an Int (or UInt). The example above should then have an Int of 49.

I am using XCode 7 Swift 2.

Any help in accomplishing this would appreciated, thanks...

• Re: Convert Hex value to Integer, XCode 7, Swift 2  Level 8 (6,565 points)

You should use strtoul.

let originalString = "<ff>"
let string = originalString.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>"))
let value = UInt8(strtoul(string, nil, 16))

Have a look here :

http : / / stackoverflow.com/questions/28621247/hex-to-decimal-swift

• Re: Convert Hex value to Integer, XCode 7, Swift 2  Level 8 (5,415 points)

You have no need to create `timestampHex`.

`<31000000>` is representing a byte sequence of 0x31 0x00 0x00 0x00, and it's a right representation of 0x00000031 in little endian.

let tsData = characteristic.value
print("         timeStamp value: \(characteristic.value)")
let count = tsData!.length / sizeof(UInt32)
let uint32Ptr = UnsafePointer<UInt32>(tsData!.bytes)
let timestamps: [UInt32] = (0..<count).map {
UInt32(littleEndian: uint32Ptr[\$0])
}
print(timestamps) //->

If you can make your code "platform dependent", as for now all Swift supported platforms are little endian.

So, this also works:

let tsData = characteristic.value
print("         timeStamp value: \(characteristic.value)")
let count = tsData!.length / sizeof(UInt32)
var array = [UInt32](count: count, repeatedValue: 0)
tsData!.getBytes(&array, length: count * sizeof(UInt32))
print(array) //->

• Re: Convert Hex value to Integer, XCode 7, Swift 2  Apple Staff (11,985 points)

For a single item I would do this like this

let d = Data(bytes: [0x31, 0x00, 0x00, 0x00])
guard d.count == MemoryLayout<UInt32>.size else {
… handle this error …
}
let u = d.withUnsafeBytes { (p: UnsafePointer<UInt32>) -> UInt32 in
return UInt32(littleEndian: p.pointee)
}

Or for an array like this:

let d = Data(bytes: [0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00])
guard d.count % MemoryLayout<UInt32>.size == 0 else {
… handle this error …
}
let count = d.count / MemoryLayout<UInt32>.size
let u = d.withUnsafeBytes { (p: UnsafePointer<UInt32>) -> [UInt32] in
let bp = UnsafeBufferPointer(start: p, count: count)
return bp.map { UInt32(littleEndian: \$0) }
}

I like withUnsafeBytes(_:) for this sort of thing because:

• it automatically does the right thing with regards Swift’s aliasing rules (SE-0107 UnsafeRawPointer API)

• it’s safer, because the unsafe pointers is constrained to within the closure (unless you go out of your way to do something silly)

• I prefer working with Data rather than NSData

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"

• Re: Convert Hex value to Integer, XCode 7, Swift 2  Level 1 (0 points)

Thanks for the replies. I've gone with OOPer's first solution and it is working.