4 Replies
      Latest reply: Oct 12, 2016 3:58 AM by aranel_rauta RSS
      aranel_rauta Level 1 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)")

         

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

        • Re: Convert Hex value to Integer, XCode 7, Swift 2
          Claude31 Level 5 Level 5 (1,915 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
            OOPer Level 7 Level 7 (3,565 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) //->[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]
            
            
              • Re: Convert Hex value to Integer, XCode 7, Swift 2
                eskimo Apple Staff Apple Staff (7,550 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
                  aranel_rauta Level 1 Level 1 (0 points)

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