Author Topic: IOS APPS in swift language  (Read 19878 times)

mrwilljackson

  • RFduino Newbie
  • *
  • Posts: 14
  • Karma: +0/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #15 on: November 30, 2014, 02:16:46 AM »
Thanks Tolson and Maverik  ;D

to be honest i'm struggling here - I also don't understand how to do this in swift. in fact I don't fully understand the conversion after googling and endianness....(what - I have no idea!).

it seems that RFduino.m lines 60 - 65 seem to contain the conversion?! I'm afraid I don't have enough understanding and knowledge yet to appreciate whats going on  :P

With a little objectiveC class with the following method, the values seem to be converted and float values are shown in the log

Code: [Select]
-(float)returnFloat:(NSData*)data {
        uint8_t *p = (uint8_t*)[data bytes];
        NSUInteger len = [data length];
        return (sizeof(float) <= len ? *(float*)p : 0);
}

If I can find a way to do this in swift i'll post it here ;-)

thanks again

maverik0106

  • RFduino Jr. Member
  • **
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #16 on: November 30, 2014, 01:29:47 PM »
I was going to post that function as well, you beat me to it... yes I tried converting it into swift code, but what gets me is that you can't do [data bytes] anymore...

I found someone's similar problem on Stack Overflow, but the code he was given was to solve for a 2 - byte data arrangement... So I tried (To my best knowledge) to accomodate for 4 bytes.... I know this may be completely wrong but will try it as soon as I get a chance (Don't have my usual setup around me right now)...

Code: [Select]
                // Ok this part doesn't work... it needs to use a UnsafePointer somehow... I just don't know how to use/initialize one...
                let rawValue:UInt32 = characteristic.value //I'm assuming its 32 bits integer because its 4 bytes?
       
                // Build NSData payload
                var wrapout:NSNumber = NSNumber(unsignedInt: rawValue)
                var payload : NSData = NSData(bytes: &wrapout, length: rawValue.length)

                // Extracting data
                var finalValue = 0

                if payload.length >= rawValue.length {

                    var wrapin   : NSNumber = NSNumber(unsignedInt: 0)
                    var bstring  : UInt32 = 0

                    payload.getBytes(&wrapin, range: NSRange(location: 0, length: rawValue.length))
                    bstring = wrapin.unsignedIntValue

                    let values : UInt32 = bstring & 0b0000_0001_1111_1111_1111_1111_1111_1111
                    let valsign: UInt32 = (bstring & 0b0000_0000_1000_0000_0000_0000_0000_0000) >> 31

                    if valsign == 0 {
                        finalValue = Int(values)
                    } else {
                        finalValue = -1 * Int(values)
                    }
                }
                println("\(finalValue)")

While I don't understand this, it seems to have worked for the guy... I just wished any iStuff guru could help us here :) please...

Thanks
« Last Edit: November 30, 2014, 03:02:08 PM by maverik0106 »

bsiever

  • RFduino Full Member
  • ***
  • Posts: 89
  • Karma: +4/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #17 on: November 30, 2014, 04:52:02 PM »
Here's some Swift code to do both: a) reverse the byte order for a 32-bit UInt and b) Reinterpret the bits of an integer type as a Float (also: c) print it out to the console). I think it's a bit easier to follow.  I used the value from your earlier example as a test case.

Code: [Select]
// Assuming a variable (test) contains the UInt32 in reverse byte order
var test:UInt32 = 0x00a465be
var reversed = test.byteSwapped
var floatVal:Float = unsafeBitCast(reversed, Float.self)
println(floatVal)

  Bill
« Last Edit: November 30, 2014, 04:57:31 PM by bsiever »

maverik0106

  • RFduino Jr. Member
  • **
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #18 on: November 30, 2014, 05:46:15 PM »
Hi Bill,

YESSSS!!!! YESS!!!! As Anakin Skywalker said when he got his pod racer running: "It's Working!, It's Working!!!!!"
This is Gold! Platinum and Diamonds! all in a basket!

You sir have made my day much much brighter and warm here in the dark and cold Canada!
I will be putting a huge thanks note on my app when and if I get it out on the app store! lol... I'm already thinking I'll have an app on the app store yay! before it was just a dream!....

Ok so now that the rant is done, here is the follow up...

It does not compile, but the reason it does not compile is because I'm receiving a NSData type variable, and we cannot simply typecast an NSData type to a UInt32...

I was trying to do it with an unsafePointer, but I can't remember how I did it yesterday (which was working) but also I'm unsure whether I should continue pursuing it doing it that way...

I also tried to type cast it as a AnyObject and then right after as a UInt32... but I guess it got lost in translation... as:

println(characteristic.value as AnyObject as UInt32)... no good....

Thanks a lot Bill, if you could help a bit more that'd be amazing!


bsiever

  • RFduino Full Member
  • ***
  • Posts: 89
  • Karma: +4/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #19 on: November 30, 2014, 06:32:12 PM »
Thanks a lot Bill, if you could help a bit more that'd be amazing!

Sure. If your NSData variable is named "data":

Code: [Select]
var uint: UInt32 = 0
// Convert the NSData into a uint
data.getBytes(&uint, length: sizeof(NSInteger))
var reversedUint = uint.byteSwapped
var floatVal:Float = unsafeBitCast(reversedUint, Float.self)
println(floatVal)

That's my first attempt...There may be a better approach,

  Bill

maverik0106

  • RFduino Jr. Member
  • **
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #20 on: November 30, 2014, 06:44:34 PM »
Awesome!

I tried something similar:

Code: [Select]
                var bin32:UInt32 = 0
                characteristic.value.getBytes(&bin32, range: NSRange(location: 0,length:characteristic.value.length))
                var reversed = bin32.byteSwapped
                var floatVal:Float = unsafeBitCast(reversed, Float.self)
                println(floatVal)

From that I received the following output:

Code: [Select]
<0000bb43>
6.71768e-41

<0000bb43>
6.71768e-41

<00003d44>
2.1978e-41

<00c07f44>
1.76781e-38

Some of the values you may recognize (00c07f44 --> 1023) etc... So I'm not sure why its doing this... when I do it statically as a 0x00c07F44 it does output 1023, but when I do it dynamically from the NSData received it gives me 1.76781e-38... I'm assuming then that we're flipping the wrong bits? or maybe its not actually a UInt32?

I'll give your code a try and update soon... Thanks

Updated:

Output from the conversion of your code renders essentially the same values... I'm considering upgrading from UInt32 to UInt64 or downgrading down to UInt16...

Is it wrong to assume my values are 4 bytes long because I'm getting that value from doing characteristic.value.length = 4?
But we're using the actual length not a fixed value...

hmm... need to ponder on that
« Last Edit: November 30, 2014, 06:49:38 PM by maverik0106 »

bsiever

  • RFduino Full Member
  • ***
  • Posts: 89
  • Karma: +4/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #21 on: November 30, 2014, 06:53:26 PM »
When you reverse the bytes on 00c07f44 (to 447fc000) and convert it to a Float it should be 1023.0 (as you noted).
(The other two should be: 00003d44 becomes 756.0 & 0000bb43 becomes 374.0).

The values that you are showing are the result of the bytes being interpreted in the other order (MSB on the left / big-endian). Either you don't need to reverse them or you are somehow reversing them twice.

Try just:
Code: [Select]
var bin32:UInt32 = 0
characteristic.value.getBytes(&bin32, range: NSRange(location: 0,length:characteristic.value.length))
var floatVal:Float = unsafeBitCast(bin32, Float.self)
println(floatVal)

  Bill
« Last Edit: November 30, 2014, 06:57:04 PM by bsiever »

maverik0106

  • RFduino Jr. Member
  • **
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #22 on: November 30, 2014, 06:59:51 PM »
I did notice one thing:

When I print out characteristics.value I get the following number: 00c07f44, but when we do the "static" way without using the NSData received, we add a 0x.... and it won't compile if I remove the 0x from the number so 0x00c07f44...

would that have something to do with it? if so how would I append the 0x to 00c07f44 without adding length to the value...

I am just running the function to swap once, literal copy paste of the code is:

Code: [Select]
                println(characteristic.value)
                var test:UInt32 = 0
               
                characteristic.value.getBytes(&test, length: sizeof(NSInteger))
                var reversed = test.byteSwapped
                var floatVal:Float = unsafeBitCast(reversed, Float.self)
                println(floatVal)

bsiever

  • RFduino Full Member
  • ***
  • Posts: 89
  • Karma: +4/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #23 on: November 30, 2014, 07:05:18 PM »
we add a 0x.... and it won't compile if I remove the 0x from the number so 0x00c07f44...

The 0x just indicates that you are writing the value using hexadecimal rather than decimal (the default). You get the syntax error when you remove the 0x because a decimal number shouldn't have a "c" or an "f" in it.

Just try removing the byte reversal. I updated my last post to show how, but perhaps you had already read it before I updated it.

  Bill

maverik0106

  • RFduino Jr. Member
  • **
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #24 on: November 30, 2014, 07:12:56 PM »
Oh just saw your last post sorry!

I'm afraid you're right! there was no need to swap the bits... this is weird... or I find it weird, because on the LightBlue app, it shows that the format the data was found was as a 4-byte Float little Endian...

Wow it works!! I am completely speechless! I could jump right now like a happy monkey all over the place if I could!!
This truly is really appreciated! you did this in less than an hour when I've been looking and trying and searching and googling and stackoverflowing for 2 days now...

I would like to shake your hand sir! also if you live in Toronto or ever come by I would like to buy you coffee!

I am wondering tho which do you think its less memory consuming for the app, this implementation or using a memcpy function?

 

mrwilljackson

  • RFduino Newbie
  • *
  • Posts: 14
  • Karma: +0/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #25 on: December 01, 2014, 03:16:07 AM »
brilliant - many thanks for the help guys  8) more free coffee for you both in Cambridge, UK if you're ever passing ;D

bsiever

  • RFduino Full Member
  • ***
  • Posts: 89
  • Karma: +4/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #26 on: December 01, 2014, 05:20:05 AM »
I'm afraid you're right! there was no need to swap the bits... this is weird... or I find it weird, because on the LightBlue app, it shows that the format the data was found was as a 4-byte Float little Endian...

I didn't have time to look at all the details of the earlier messages and was under the impression that byte order needed to be reversed. I'd have to spend a little time digging through the details to see why/when it is/isn't needed.

I am wondering tho which do you think its less memory consuming for the app, this implementation or using a memcpy function?

It looks like any extra memory is local variables and the space is no longer in use after the conversion is done, so it shouldn't have much impact on memory use. If your iOS app is struggling for a few extra bytes for a few microseconds you've got bigger problems to deal with...

Doing an extra copy of a few bytes may take a little extra time, but most Apps have far more significant time/memory issues that should be dealt with before micromanaging small, infrequent data conversions like this. (Often the compiler/run-time do all sorts of optimizations --- micromanaging code for time/space takes a lot of effort and study to be effective on a platform like iOS. It's usually best to focus on the big-picture items first: code clarity, good code architecture, correctness, and efficiency of high-level algorithms.)

mrwilljackson & maverik0106: Thanks, I'll have to take a rain check on the coffee,
  Bill

maverik0106

  • RFduino Jr. Member
  • **
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #27 on: December 01, 2014, 08:36:29 AM »
Well I was more concerned on the fact that its not the only type of transformation I will be doing on the app, so converting NSData to Float is coming from continuous analog values...

So at the speed the rfduino can send it and the iphone receive it will be doing that many conversions... that plus possibly storing those values or sending them through wifi after or even 3G to store...

That's why I'm worried about bottlenecking data flow. But its probably not a big deal at this moment/point.

Thanks again really!

bsiever

  • RFduino Full Member
  • ***
  • Posts: 89
  • Karma: +4/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #28 on: December 02, 2014, 06:09:36 AM »
If the bytes don't need to be reversed you could just do (again, assuming that data is an NSData object):

Code: [Select]
var fv:Float = 0.0;
data.getBytes(&fv, length:sizeof(Float))
println(fv)

It's a bit cleaner.
  Bill
« Last Edit: December 02, 2014, 06:11:42 AM by bsiever »

maverik0106

  • RFduino Jr. Member
  • **
  • Posts: 59
  • Karma: +0/-0
    • View Profile
Re: IOS APPS in swift language
« Reply #29 on: December 02, 2014, 06:46:26 AM »
Well you even managed to reduce the number of lines!

I am using instruments on Xcode, it seems to run faster for sure, also you managed to remove the unsafeCast! How many years have you been doing software development? I'd like one day to program like you :).

I appreciate taking the time to look at the code again!

It seems that I'm getting close to getting a demo app, and I would like to put a thank you note for contributors, so if you want to PM me with info you'd like to display for your amazing contribution I'd be more than glad to put you there :)


 

anything