Convert Hex value to Integer, XCode 7, Swift 2

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)")


Notification received:

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...

Accepted Reply

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) //->[49]


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) //->[49]

Replies

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

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) //->[49]


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) //->[49]

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"

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