Error converting int into NSNumber - ios

I am fetching data from the web, and I am having problems with the numbers that are returned. For example, when the int 1 is returned from the server, and I try and convert that int to a NSNumber, the value of the NSNumber is 151241152. The number is slightly different every time, but it is always over 1 billion. Here is my code:
int agrees = (int)[info objectForKey:kWaveAgrees];
wave.numberOfAgrees = [NSNumber numberWithInt:agrees];
Does anyone know why this is happening?

NSNumber is an object. You cannot cast it into an int, it must be unboxed first.
int agrees = [[info objectForKey:kWaveAgrees] intValue];

Related

IOS/Objective-C: Get Number from JSON

I have a JSON dictionary that contains what I will call an integer (in mathematics) i.e. 1.
I would like to save this number to a core data attribute that is an NSInteger. The following code is issuing warning:
Incompatible Pointer to Integer Conversion initializing NSInteger with an expression of type 'id'
NSInteger insertID = jsonResults[#"insert_id"];
I have tried various combinations of int, NSNumber, etc. to no avail. Can anyone suggest right way to do this?
NSDictionary can't store NSInteger. It is storing NSNumber. So you need to unwrap the NSNumber:
NSInteger insertID = [jsonResults[#"insert_id"] integerValue];
in core data you should save numeric value as Number Type.
For eaxample,
To save:
insert_id = #(100)//say 100 is your insert_id value
To read:
NSInteger insertID = [jsonResults[#"insert_id"] intValue];

iOS converting value in NSDictionary with (int) fail

I had a NSDictionary contains 2 key/value pairs:
NSDictionary *dic = #{#"tag":#2, //NSNumber
#"string":#"someString"}; //NSString
NSLog(#"%i",(int)[dic objectForKey:#"tag"]); //print out 34
NSLog(#"%i",[dic objectForKey:#"tag"] intValue]); //print out 2
Why does "converting id value to int with (int)"get me the wrong result but not the other way? are they in different levels of conversion?
Why does "converting id value to int with (int)"get me the wrong result but not the other way? are they in different levels of conversion?
id is a pointer type. id pointers point to Objective-C objects in memory. By casting id to (int), you are merely reinterpreting (some of) the pointer's bit pattern as an int, which is quite meaningless. You have to call the proper conversion methods of NSString and NSNumber if you want to reliably get the primitive values out of the Objective-C object.
If you ever seemingly get the "correct" value of 2 in the case of pointer-casting with NSNumber, that may be because the Objective-C runtime makes use of an optimization technique called tagged pointers, whereby small objects are not really created and allocated, but their semantics (the number's bits which the NSNumber object stores) is stuffed into the unused bits of the pointer.
#2 is not an int but a NSNumber you can't cast an NSNumber into an int. You have to use intValue method to get the correct result.
The method objectForKey: returns a pointer to the NSNumber object #2, not the value stored in the object itself. So you're typecasting the pointer, not the value 2. In the last line you don't typecast the object but you access a property called intValue which returns the value of the object expressed as an int.
NSDictionary contains Object with Key value pairs,but you passed int(#2) into object
NSDictionary *dic = #{#"tag":#2, //NSNumber
#"string":#"someString"};
so Change int to NSNumber like
NSDictionary *dic = #{#"tag":[NSNumber numberWithInt:2];,#"string":#"someString"};
and you can get it..
int number = [[dict objectForKey:#"tag"] intValue];

Number from NSDictionary

This is the code I'm using to pull a number from a dictionary,
int num = [[sharedManager.data objectForKey:#"sum(units.num)"]intValue];
This is the key/value of the number which is printed in the debugger.
key = (__NSCFString *) #"sum(units.num)" 0x176d4d40
value = (__NSCFNumber *) (long)38244 0x176ca850
And this is the result I'm getting,
num = (int) 393051808
What i need is for num to be 38244.
Does anyone know why I'm getting this result?
Thanks
Paul.
What you are getting is , the integer representation (393051808) of your key's memory address (0x176d4d40).
Do this,
NSNumber *number = [sharedManager.data objectForKey:#"sum(units.num)"];
int num = [number intValue];
// or
long num = [number longValue]; //because your number is a long value

Converting int to NSString

I thought I had nailed converting an int to and NSString a while back, but each time I run my code, the program gets to the following lines and crashes. Can anyone see what I'm doing wrong?
NSString *rssiString = (int)self.selectedBeacon.rssi;
UnitySendMessage("Foo", "RSSIValue", [rssiString UTF8String] );
These lines should take the rssi value (Which is an NSInt) convert it to a string, then pass it to my unity object in a format it can read.
What am I doing wrong?
NSString *rssiString = [NSString stringWithFormat:#"%d", self.selectedBeacon.rssi];
UPDATE: it is important to remember there is no such thing as NSInt. In my snippet I assumed that you meant NSInteger.
If you use 32-bit environment, use this
NSString *rssiString = [NSString stringWithFormat:#"%d", self.selectedBeacon.rssi];
But you cann't use this in 64-bit environment, Because it will give below warning.
Values of type 'NSInteger' should not be used as format arguments; add
an explicit cast to 'long'
So use below code, But below will give warning in 32-bit environment.
NSString *rssiString = [NSString stringWithFormat:#"%ld", self.selectedBeacon.rssi];
If you want to code for both(32-bit & 64-bit) in one line, use below code. Just casting.
NSString *rssiString = [NSString stringWithFormat:#"%ld", (long)self.selectedBeacon.rssi];
I'd like to provide a sweet way to do this job:
//For any numbers.
int iValue;
NSString *sValue = [#(iValue) stringValue];
//Even more concise!
NSString *sValue = #(iValue).stringValue;
NSString *rssiString = [self.selectedBeacon.rssi stringValue];
For simple conversions of basic number values, you can use a technique called casting. A cast forces a value to perform a conversion based on strict rules established for the C language. Most of the rules dictate how conversions between numeric types (e.g., long and short versions of int and float types) are to behave during such conversions.
Specify a cast by placing the desired output data type in parentheses before the original value. For example, the following changes an int to a float:
float myValueAsFloat = (float)myValueAsInt;
One of the rules that could impact you is that when a float or double is cast to an int, the numbers to the right of the decimal (and the decimal) are stripped off. No rounding occurs. You can see how casting works for yourself in Workbench by modifying the runMyCode: method as follows:
- (IBAction)runMyCode:(id)sender {
double a = 12345.6789;
int b = (int)a;
float c = (float)b;
NSLog(#"\ndouble = %f\nint of double = %d\nfloat of int = %f", a, b, c);
}
the console reveals the following log result:
double = 12345.678900
int of double = 12345
float of int = 12345.000000
original link is http://answers.oreilly.com/topic/2508-how-to-convert-objective-c-data-types-within-ios-4-sdk/
If self.selectedBeacon.rssi is an int, and it appears you're interested in providing a char * string to the UnitySendMessage API, you could skip the trip through NSString:
char rssiString[19];
sprintf(rssiString, "%d", self.selectedBeacon.rssi);
UnitySendMessage("Foo", "RSSIValue", rssiString );

How do I use a core data Integer 64 property?

I want to have an Entity property in Core Data be a 64-bit integer. Since the model is going to run on iOS, and as far as I know these devices are not 64-bit, I figured that NSNumber was the way to go (core data gives you the option of objects or scalar properties for primitive types).
I'm assuming that NSNumber will internally take care of keeping track of a suitable representation for 64 bits.
Now, I need to subtract 1 from this "64 bit" property in my entity at some point (in case you didn't guess, the 64 bit property is the max_id parameter in the Twitter API), but to do so, I first need to unbox the number inside the NSNumber property.
So should i get the intValue? longValue? unsignedIntValue? unsignedLongValue? long long? which one?
Since you already know the type (64 bit integer), you don't need to check for it.
To get a 64 bit integer out of a NSNumber, do one of the following:
NSInteger myInteger = [myNSNumber integerValue];
int64_t myInteger = [myNSNumber integerValue];
In order to just add one to it, you can use something like this:
myNSNumber = [NSNumber numberWithInteger:[myNSNumber integerValue]+1]];
Note that iOS does have 64 bit data types like int64_t and NSInteger.
EDIT:
If the only reason that you are using NSNumber is to store the 64 bit integer, you can just declare the property like this in your model subclass and skip the unboxing/boxing altogether:
#property (nonatomic) int64_t myIntValue;
Note that core data does this by default if you select the Use scalar properties for primitive data types option of the Create NSManagedObject Subclass feature.
Try putting this in a NSNumber category:
-(int64_t) int64value
{
if (sizeof(short) == 8)
return [self shortValue];
if (sizeof(int) == 8)
return [self intValue];
if (sizeof(long) == 8)
return [self longValue];
if (sizeof(long long) == 8)
return [self longLongValue];
return -1; // or throw an exception
}
To get the C type contained in NSNumber use objCType
Example
NSNumber *myFloat = [NSNumber numberWithFloat:5.5f];
NSLog(#"%s", [myFloat objCType]);
Will print "f" as it contains a value of type float.
Also, check out #encode() which will return a C type character.
Example
NSNumber *myFloat = [NSNumber numberWithFloat:5.5f];
if (strcmp(myFloat) == #encode(float)) {
NSLog(#"This is a float");
}
Also
NSNumber *myFloat = [NSNumber numberWithFloat:5.5f];
CFNumberType numberType = CFNumberGetType((CFNumberRef)myFloat);

Resources