Convert NSNumber to long - ios

I am trying to convert a NSNumber to long but I get this error:
[__NSSingleObjectArrayI intValue]: unrecognized selector sent to
instance
Here is my code:
NSNumber *dbversion = [settings valueForKey:#"Version"];
long dbver = [dbversion longValue];
What am I doing wrong here?
*settings is a NSArray and "Version" is the key for a long value.

You are caught in the Key-Value Coding trap.
In some cases the result of valueForKey is an array which the error message clearly states.
Don't Never use valueForKey(unless you know what KVC does and you need KVC), use key subscription.
And as settings is an array you might get the first item
NSNumber *dbversion = settings[0][#"Version"];
and int is not long
long dbver = [dbversion longValue];
However on a 64-bit machine I recommend to use NSInteger
NSInteger dbver = dbversion.integerValue;

//I think you are storing string from dictionary "settings" to NSNumber so it's showing error like you mention in question.
Please Try with solution. May this help you.
NSNumber *dbversion = [NSNumber numberWithLong:[[settings valueForKey:#"Version"] longLongValue]];
int dbver = [dbversion longValue];

Related

How to get the value for key #int from NSDictionary?

I am Creating a NSDictionary and adding a key value pair as below
NSDictionary* dictionary = #{ #0: #"I am the value" };
and retrieving the value as below
NSString* value = [dictionary valueForKey:#0];
Application crashed for doing this, I don't understand the reason, I am giving the same data type and value.
What is the datatype of #0, I guess it is NSNumber, If not correct me.
Yes, it's NSNumber type however the problem is somewhere else.
You should call objectForKey instead of valueForKey which is mainly used for KVO.
NSString *value = [dictionary objectForKey:#0];
or better:
NSString *value = dictionary[#0];
valueForKey: is not the proper method for what you are trying to achieve.
you should use:
NSString* value = [dictionary objectForKey:#0];
ValueForKey is for key value coding and expect a NSString as parameters

Use existing string as valueForKey value

I am trying to use a string ("levelNumberString") as a valueForKey in an NSDictionary. When I use a string like #"1", it all works perfectly, but when I decide to swap out that kind of string for levelNumberString, it gives me a SIGABRT error. The integer levelInt is an integer that decides what level the app is at. When the view is loaded, it is worth 1, and its value is taken up by the "levelNumberString" string.
This is my code (it's in viewDidLoad, if that helps at all):
NSString *levelNumberString = [NSString stringWithFormat:#"i%", levelInt];
NSDictionary *packDict = [NSDictionary dictionaryWithDictionary:[rootDict valueForKey:levelNumberString]];
The above code is what is giving me the error.
Thanks in advance!
The problem is over here #"i%" it should be #"%i"
NSString *levelNumberString = [NSString stringWithFormat:#"%i", levelInt];
NSDictionary *packDict = [NSDictionary dictionaryWithDictionary:[rootDict valueForKey:levelNumberString]];

Getting a warning in XCode about an NSMutableDictionary key that should be NSNumber

So I have the following in an Xcode 6.3 project where I have _menuHeaderPositions which should hold a keys of a menuHeaderID and an NSNumber which represents the contentOffset:
// _menuHeaderPositions is a NSMutableDictionary
// should be a NSNumber created from an NSUInteger
[_menuHeaderPositions setObject:[NSNumber numberWithFloat:_runningYPosition] forKey:[NSNumber numberWithInteger:menuHeader.menuHeaderID]];
// so unsigned long because of complaints about int
firstButton.tag=(unsigned long)menuHeaderID;
... later firstButton -> thisTap.view
// Works Fine
NSLog(#"you tapped me %lu", [_menuHeaderPositions objectForKey:[NSNumber numberWithInteger: thisTap.view.tag]]);
// THIS IS THE ISSUE
// Implicit Conversion loses integer precision: 'NSInteger' (aka long) to 'int'
NSNumber *pos=[_menuHeaderPositions objectForKey:[NSNumber numberWithInt:thisTap.view.tag]];
But I get this error and am pretty clueless as to what is going on here:
Implicit Conversion loses integer precision: 'NSInteger' (aka long) to 'int'
I can access the correct value later as [pos floatValue] but how do I get this warning to go away?
edit 1
trying this didn't seem to work:
NSNumber *pos=[_menuHeaderPositions objectForKey:[NSNumber numberWithInt:#(thisTap.view.tag)]];
The tag property has a type of NSInteger. You are attempting to pass this NSInteger to a method (numberWithInt:) that expects an int.
You have two choices:
Use NSNumber numberWithInteger:
NSNumber *pos=[_menuHeaderPositions objectForKey:[NSNumber numberWithInteger:thisTap.view.tag]];
Use modern boxing: #(thisTap.view.tag)
NSNumber *pos=[_menuHeaderPositions objectForKey:#(thisTap.view.tag)];
You can also use modern dictionary syntax and the line simply becomes:
NSNumber *pos = _menuHeaderPositions[#(thisTap.view.tag)];
First you should clear the data type of your menuHeader.menuHeaderID, which has two identity —— the key of the dictionary and the tag of the view.
As #rmaddy said, the tag property of the UIButton has type of NSInteger, which is NOT simply int.
This is the doc of numberWithInt: and numberWithInteger:.
Briefly speaking, use numberWithInteger: rather than numberWithInt:.
firstButton.tag = (NSInteger)menuHeaderID;
NSNumber *pos = [_menuHeaderPositions objectForKey:[NSNumber numberWithInteger:thisTap.view.tag]];

Creating NSNumber with a #define variable

From my understanding of NSNumber, if you create NSNumber with a certain data type, you need to access the variable with that same data type. For example
NSNumber *myIntNumber = [NSNumber numberWithInt:1];
int myInt = [myIntNumber intValue];
NSNumber *myNSIntegerNumber = [NSNumber numberWithInteger:1];
NSInteger myInteger = [myIntNumber integerValue];
If a NSNumber is created using a #define variable:
#define MY_DEFINE 6
does that mean that I cannot do the following
NSNumber *myNSIntegerNumber = [NSNumber numberWithInteger:MY_DEFINE];
NSInteger myInteger = [myIntNumber integerValue];
because MY_DEFINE is not a NSInteger?
I know that the above code would work in a 32-bit app, but I am trying to make sure that it will work on a 64-bit app, which is much more picky about these things, as well. And of course, it never hurts to do things properly.
If I cannot do the above, should I try to define MY_DEFINE differently so that I could use it to create a NSNumber that can later be used to retrieve a NSInteger?
Your understanding of NSNumber is incorrect. You can create an NSNumber with any type it supports and you can then use any of the supported type accessors. The two do not need to the same.
// Perfectly valid
NSNumber *number = [NSNumber numberWithFloat:3.14];
int val = [number intValue]; // results in 3
Your use of the #define is perfectly valid. The pre-compiler simply translates your code to:
NSNumber *myNSIntegerNumber = [NSNumber numberWithInteger:6];
Remember, a #define is nothing more than simple copy and paste (at least in this type of simple form) done before the code is compiled.
You can even use modern syntax:
NSNumber *number = #MY_DEFINE;
which becomes:
NSNumber *number = #6;
BTW - why post this question? Why not just try it first?

Failed to save double Value in NSUSerDefault

Hi everybody :) i want to save a double Value into NSUserDefault like this:
NSUserDefaults *startValues = [NSUserDefaults standardUserDefaults];
[startValues setDouble:[[self.dataList objectAtIndex:indexPath.row]doubleValue] forKey:#"lat"];
[startValues synchronize];
I get no Errors or Warnings from Xcode, but when i run the Code, it crashes with the Message:
-[__NSCFDictionary doubleValue]: unrecognized selector sent to instance
I also tried to split up the Code like:
double lat = [[self.dataList objectAtIndex:indexPath.row]doubleValue];
[startValues setDouble:lat forKey:#"lat"];
but of course, i get the same error. Whats the Problem?
Thanks for your time and help :)
The problem is that [self.dataList objectAtIndex:indexPath.row] contains a dictionary. NSDictionary does not understand the doubleValue message.
You have to somehow extract the double value from the dictionary:
NSDictionary *dictionary = self.dataList[indexPath.row];
double value = [dictionary[#"latitude"] doubleValue];
[startValues setDouble:value forKey:#"lat"];

Resources