Get input from UITextField(HEX) data and send out via bluetooth LE - ios

i'm currently trying to get the data(HEX) from UITextfield, and i would want to store the data in UInt8 i'm currently doing this.
let incomingdata = UInt8(textfield.text!)
by doing this it returns nil. The purpose i'm doing this because after i gets the data from UITextField, i would send out the data in UInt8 format via bluetooth. Can someone suggest me how can i do that?Thank you
I update my question, in short i input 72AE in UITextField, i get the text in string format, but in the end i wan to convert it to UInt8 and it is in 0x72, 0xAE
In short, i'm converting HexString to UInt8

You can convert a hex value to an Int with this code.
let hex2int = String(format:"%2X", hex)
Quite easy.

I might be misunderstanding your question, but if you would like to covert string into array of Int, this is how you might go about it.
let stringFromTextField = "anything"
// Convert stringFromTextField to NSString and then then convert it to NSData
// in encoding of your choosing
if let data = NSString(string: stringFromTextField).dataUsingEncoding(NSUTF8StringEncoding) where data.length > 1 {
// Create buffer
var buffer: Int = 0
let bufferSize = 1
let adjustedDataLenght = data.length / bufferSize
var yourInt = [Int]()
// Loop over data and get bytes
for i in 0..<adjustedDataLenght {
data.getBytes(&buffer, range: NSRange(location: i, length: bufferSize))
yourInt.append(buffer)
}
// Here are your ints
print(yourInt)
}
Works in playground. Hope it helped.

Related

How do I convert an NSData object with hex data to ASCII in Swift?

I have an NSData object with hex data and I want to convert it to an ASCII string. I've seen several similar questions to mine but they are all either in Objective-C and/or they convert a string into hex data instead of the other way around.
I found this function but it doesn't work in Swift 2 and the Apple documentation doesn't explain the difference between the old stride and the new stride (it doesn't explain stride at all):
func hex2ascii (example: String) -> String
{
var chars = [Character]()
for c in example.characters
{
chars.append(c)
}
let numbers = stride(from: 0, through: chars.count, by: 2).map{ // error: 'stride(from:through:by:)' is unavailable: call the 'stride(through:by:)' method instead.
strtoul(String(chars[$0 ..< $0+2]), nil, 16)
}
var final = ""
var i = 0
while i < numbers.count {
final.append(Character(UnicodeScalar(Int(numbers[i]))))
i++
}
return final
}
I don't know what stride is and I don't know what it does.
How do you convert hex to ASCII in Swift 2? Maybe an NSData extension...
Thanks!
try:
let asciiString = String(data: data, encoding: NSASCIIStringEncoding)
print(asciiString)
Sorry for answering my own question, but I just (accidentally) found an amazing solution to my problem and hopefully this will help someone.
If you have an NSData object with a hex representation of an ASCII string, then all you have to do is write String(data: theNSDataObject, encoding: NSUTF8StringEncoding) and that is the ASCII string.
Hope this helps someone!
In swift 2.0 stride became a method on Int rather than a standalone method so now you do something like
0.stride(through: 10, by: 2)
So now the code you posted should be:
func hex2ascii (example: String) -> String {
var chars = [Character]()
for c in example.characters {
chars.append(c)
}
let numbers = 0.stride(through: chars.count, by: 2).map{
strtoul(String(chars[$0 ..< $0+2]), nil, 16)
}
var final = ""
var i = 0
while i < numbers.count {
final.append(Character(UnicodeScalar(Int(numbers[i]))))
i++
}
return final
}

swift2 decrypt MD5

Hello I just want to decrypt from md5 to 'normal string'
extension String {
func MD5() -> String {
var data = (self as NSString).dataUsingEncoding(NSUTF8StringEncoding)
let result = NSMutableData(length: Int(CC_MD5_DIGEST_LENGTH))
let resultBytes = UnsafeMutablePointer<CUnsignedChar>(result!.mutableBytes)
CC_MD5(data!.bytes, CC_LONG(data!.length), resultBytes)
let buff = UnsafeBufferPointer<CUnsignedChar>(start: resultBytes, count: result!.length)
let hash = NSMutableString()
for i in buff {
hash.appendFormat("%02x", i)
}
return hash as String
}
var x = "abc".MD5()
I want to get back to abc from "x"
It's not possible that's the whole point of hashing. You can however bruteforce by going through all possibilities (using all possible digits characters in every possible order) and hashing them and checking for a collision.
it was hard to reverse.
also check...https://en.wikipedia.org/wiki/MD5
Simple: Not possible, because MD5 hash is not possible to invert.
Check about One way function

How to create a NSData from hex value in swift

I'm a swift/iOS newbie and I have a problem to solve.
I'm trying to get data from Texas Instrument SensorTag 2. To activate a sensor, following the instructions, I have to write a binary string in the configuration bank of my sensor.
I have this snippet of code:
if SensorTag.validConfigCharacteristic(thisCharacteristic) {
// Enable Sensor
let enableByte = SensorTag.getEnableByteFor(thisCharacteristic)
self.sensorTagPeripheral.writeValue(enableByte, forCharacteristic: thisCharacteristic, type: CBCharacteristicWriteType.WithResponse)
}
and I write the function to get the value to write. enableByte type is NSData.
class func getEnableByteFor(thisCharacteristic: CBCharacteristic) -> NSData {
print(thisCharacteristic.UUID)
var enableValue = 0
if thisCharacteristic.UUID == MovementConfigUUID {
enableValue = ...
} else { // any other activation
enableValue = 1
}
return NSData(bytes: &enableValue, length: sizeof(UInt8))
}
For every sensor I have to write a 1 if I want to enable the sensor and 0 if I want to disable it, but with the movement sensor I have to write according to this guide 16 bits (2 byte). For my config I have to write a binary value of 0000000001111111, 0x007F. How can I initialize a NSData object with value 0x007F?
Try this:
let bytes : [CChar] = [0x0, 0x7F]
let data = NSData(bytes: bytes, length: 2)
NSData(bytes:length:) creates an NSData object from a byte stream. In Objective-C, this byte stream is of type char *. The Swift equivalent is [CChar]. The question (and another answer) use an Int to represent this byte stream. This is wrong and dangerous.
var enableValue = 0 // enableValue is a 64-bit integer
NSData(bytes: &enableValue, length: sizeof(UInt8)) // this trims it to the first 8 bits
It works because x86 uses Little Endian encoding, which puts the least significant byte first. It will fail on PowerPC, which uses Big Endian. ARM uses switchable endianness so it may or may not fail there. When the situation call for exact bit layout, you should not rely on the architecture's endianness:
class func getEnableByteFor(thisCharacteristic: CBCharacteristic) -> NSData {
print(thisCharacteristic.UUID)
let enableValue : [CChar]
if thisCharacteristic.UUID == MovementConfigUUID {
enableValue = [0x0, 0x7F]
} else { // any other activation
enableValue = [0x1]
}
return NSData(bytes: enableValue, length: enableValue.count)
}
Much shorter solution taking in account byte order:
NSData(bytes: [UInt16(0x007F).bigEndian], length: 2)
Now there is nothing wrong with using [UInt16] as byte stream because UInt16 has bigEndian property that returns the big-endian representation of the integer changing byte order if necessary.

Convert NSData bytes to custom object

I am starting a project to create an iOS app to communicate with a device over BLE. Being a new effort, I am trying to do this is Swift if possible. The interface uses GATT and an existing set of custom message structures. I get to a point where I have the data from BLE in an NSData object. I'd like to cast it or directly convert it to my message structure in a fairly generic way.
I know that I can extract the data by hand either directly from the byte array from the NSData object or using an NSInputStream. While that works, it could be a maintenance issue and the interface has a number of different messages in it.
Is there an easier ways to do this?
I'd be willing to create the message structures in Objective-C and do the casting there, but my knowledge of Objective-C is not much better than my knowledge of Swift.
Some sample code of what I've been playing in my playground is shown below. It all works as expected.
func getBytesFromNSData(data: NSData, start: Int) -> [UInt8] {
let count = data.length / sizeof(UInt8)
let remaining = count - start
let range = NSMakeRange(start, remaining )
var dataArray = [UInt8](count: remaining, repeatedValue: 0)
data.getBytes(&dataArray, range: range)
return dataArray
}
class TestObject {
var a: Byte
var b: Byte
init() {
a = 0x01
b = 0x02
}
init(data: NSData) {
let dataBytes = getBytesFromNSData(data, 0)
a = Byte(dataBytes[0])
b = Byte(dataBytes[1])
}
func populateFromStream(data: NSData) {
var stream = NSInputStream(data: data)
stream.open()
var bytesRead = stream.read(&a, maxLength: 1)
println("\(bytesRead)")
bytesRead = stream.read(&b, maxLength: 1)
println("\(bytesRead)")
}
func toArray() -> [Byte] {
var result = [Byte](count: 2, repeatedValue: 0)
result[0] = a
result[1] = b
return result
}
}
let test = TestObject()
let testArray = test.toArray()
let length = testArray.count
let testData = NSData(bytes: testArray, length: length)
println("\(testData)")
let testIn = [ Byte(0x0d), Byte(0x0e) ]
let testDataIn = NSData(bytes: testIn, length: testIn.count)
println("\(testDataIn)")
let testConstructor = TestObject(data: testDataIn)
var testObject = TestObject()
testObject.populateFromStream(testDataIn)
I found a method that is fairly generic that may work is some cases.
Create an Objective-C riding header
Create the data structure as an Objective-C structure
Import the header with the data structure into the bridging header
Assuming that you have a struct called Foo and an NSData object called rawData:
Use the following code to get an cast a pointer.
let structureSize = sizeof(Foo)
var myObject = UnsafeMutablePointer<Foo>.alloc(1).memory
rawData.getbytes(&myObject, length: structureSize)
This will not work in all instances and unfortunately does work in my particular case. The specific problems I have found are:
The Objective-C structure is word aligned. If your structure is not properly aligned to work boundaries, you may have a size that is incorrect. (something I ran into in my particular interface)
If you and dealing with a system that doesn't send the data in the same order you are expecting, this will not handle any byte order conversion, that would still need to be done and the structure would possibly need to be reordered to compensate. That work might negate any saving from this method.
This is the most concise method I have found if it happens to work with your particular message formats.

Swift - converting from ConstUnsafePointer<()>

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];
}
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)")
}
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.
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]")
}

Resources