How to convert and compare NSNumber to BOOL? - iphone

First I convert BOOL value to NSNumber in order to put it into NSUserDefaults. Later I would like to retrieve the BOOL value from the NSUserDefaults, but obviously I get NSNumber instead of BOOL. My questions are?
how to convert back from NSNumber to BOOL?
How to compare NSNumber to BOOL value.
Currently I have:
if (someNSNumberValue == [NSNumber numberWithBool:NO]) {
do something
}
any better way to to the comparison?
Thanks!

You currently compare two pointers. Use NSNumbers methods instead to actually compare the two:
if([someNSNumberValue isEqualToNumber:[NSNumber numberWithBool:NO]]) {
// ...
}
To get the bool value from a NSNumber use -(BOOL)boolValue:
BOOL b = [num boolValue];
With that the comparison would be easier to read for me this way:
if([num boolValue] == NO) {
// ...
}

Swift 4:
let newBoolValue = nsNumberValue.boolValue

NSUserDefaults has two methods to transparently operate with booleans:
- (BOOL)boolForKey:(NSString *)defaultName
- (void)setBool:(BOOL)value forKey:(NSString *)defaultName

The ONLY way I managed to finagle a NSNumber's "booleanity" from its NSConcreteValue(doh!) was with the following...
id x = [self valueForKey:#"aBoolMaybe"];
if ([x respondsToSelector:#selector(boolValue)] &&
[x isKindOfClass:objc_getClass("__NSCFNumber")])
[self doSomethingThatExpectsABool:[x boolValue]];
Every other trick... FAILED. Buyer beware, this isn't foolproof (__NSCFNumber may well be platform/machine specific - it is solely Apple's implementation detail)... but as they say.. nothing else worked!

Related

Condition always fails though the comparative values seems correct in iOS

When I check the value of number in nslog it shows '0'
NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
NSNumber *number=[data objectForKey:#"serial"];
NSLog(#"%#",number);
if(number ==0 )
{
imgButton.hidden=YES;
}
But the condition always fails , I also changed the code like this
NSString *number=[data objectForKey:#"serial"]
NSLog(#"%#",number);
if(number == #"0" )
{
imgButton.hidden=YES;
}
But here too the condition fail ,What is the issue with this?
In the first code you are checking a NSNumber, object, against an int.
The correct check is:
if([number intValue] == 0) {
imgButton.hidden = YES;
}
In the second code you are checking two NSString, but you have to use the "isEqualToString" method and not "==". The correct code is:
if([number isEqualToString:#"0"]) {
imgButton.hidden = YES;
}
NSNumber is an object, 0 is an integer (a primitive type). They will never be equal. But you can change the comparison like this [number intValue] == 0 and this will work when the value of your NSNumber is 0.
On the string comparison, you should use the method
isEqualToString:NSString *)string
for the comparison.
For NSNumbers its
isEqualToNumber:(NSNumber *)number
Because otherwise you arent comparing if they have the same value, but if they are stored in identical memory space.

Sort NSMutableDictionary keys by object?

Okeh. Here is the deal:
Have have a NSMutualDictionary with words as keys (say names). The value objects is a NSNumber (like rating)
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:[NSNumber intValue:1] forKey:#"Melvin"];
[dictionary setObject:[NSNumber intValue:2] forKey:#"John"];
[dictionary setObject:[NSNumber intValue:3] forKey:#"Esben"];
I want to sort them with the highest ratings first.
I know I'm going to do it like this:
[searchWords keysSortedByValueUsingSelector:#selector(intCompare:)];
But not sure how to implement intCompare. (the compare method)
Can anybody point me in the right direction?
- (NSComparisonResult) intCompare:(NSString *) other
{
//What to do here?
}
I want to get an NSArray with {Esben, John, Melvin}.
Since the objects you put into the dictionary are NSNumber instances you should change the method signature a bit. But the full implementation is really easy:
-(NSComparisonResult)intCompare:(NSNumber*)otherNumber {
return [self compare:otherNumber];
}
In fact I see no reason as to why you need to do your own intCompare: method, when you could go with the compare: that NSNumber already has.
These constants are used to indicate how items in a request are ordered.
enum {
NSOrderedAscending = -1,
NSOrderedSame,
NSOrderedDescending
};
typedef NSInteger NSComparisonResult;
That is taken from Apple's dev documentataion on Data types... now all you have to do is check which one is bigger. All of this is done for you though. Simply pass in #selector(compare:) and that should do it. As your values are NSNumbers and NSNumber implements the compare: function. Which is what you want :)
NSArray *sortedArray = [searchWords sortedArrayUsingSelector:#selector(compare:) ];
or you might well as used, here is the implementation of your intCompare selector
- (NSComparisonResult) intCompare:(NSString *) other
{
int myValue = [self intValue];
int otherValue = [other intValue];
if (myValue == otherValue) return NSOrderedSame;
return (myValue < otherValue ? NSOrderedAscending : NSOrderedDescending);
}

Problem with int in Objective C

singelton.categoryId = (int)[categories.categoriesId objectAtIndex:indexPath.row];
NSLog(#"%d", singelton.categoryId);
singelton.categoryId is from type int.
But when I try to print it number is random, but if I do this NSLog(#"%#", singelton.categoryId); the printed value is right.
I need to print it with %d.
Can someone help me?
Use intValue method to get the integer representation of a NSString/NSNumber. Try,
singelton.categoryId = [[categories.categoriesId objectAtIndex:indexPath.row] intValue];
I am assuming the array returns you an NSNumber. So try this out.
int catId = [ ((NSNumber*) [categories.categoriesId objectAtIndex:indexPath.row] ) intValue];
NSLog(#"%d, catId )
try the following:
NSLog(#"%d", [singelton.categoryId intValue]);
The category ID as returned by objectAtIndex: is an object, most probably an NSNumber. By casting it to int you get the address of the object, not the numeric value stored in it. The correct code would be something like this:
singleton.categoryID = [[… objectAtIndex:…] intValue];
Try do do this in this way:
singelton.categoryId = [[categories.categoriesId objectAtIndex:indexPath.row] intValue]
It's because you can't store ints in array - they must be NSNumbers.
There's no way that's coming from an int primitive type when it's a proper object (assuming that objectAtIndex behaves here as elsewhere in Objective-C--i.e., it's not your own method. So, you'll need to ask for the intValue:
[[categories.categoriesId objectAtIndex:indexPath.row] intValue]
if it is an available method. What class is categoriesID?

Objective-C: using if/else statement with Plist values

I'm sure this is really basic but I can't see what I'm doing wrong. Can someone help me understand where I'm going wrong please? I'm working in xcode. I'm trying to make different parts of my view appear depending on values saved in a property list. If the value assigned to a particular UITextField is equal to zero then I want to hide that UITextField. I'm trying to do this like this. gross is the name of a UITextField:
NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
gross.text = [array objectAtIndex:7];
if ([array objectAtIndex:7 == 0]) {
gross.hidden = YES;
}
else {
gross.hidden = NO;
}
[array release];
I think the problem is something to do with how I've wrote the if/else statement. I know this is really basic but I don't quite understand where I'm going wrong. So Your help is much appreciated.
Code should read:
NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
gross.text = [array objectAtIndex:7];
if ([[array objectAtIndex:7] isEqualToString:#"0"]) {
gross.hidden = YES;
} else {
gross.hidden = NO;
}
[array release];
This assumes that the object at index 7 of your array exists and is a string. If it's actually an NSNumber, then you should instead use the conditional
if ([[array objectAtIndex:7] intValue] == 0) {
Note the above line works for a string where the text contains an int, such as #"0" or #"7".
if ([[array objectAtIndex:7] intValue] == 0)
First mistake is position of closing ]. And second one is you probably have NSString in array, as you have assigned that in text property. So you need to convert it to int by using intValue.
If your array contains nsstring then your condition should look like:
if ([[array objectAtIndex:7] intValue] == 0) {
...
or
if ([[array objectAtIndex:7] isEqualToString:#"0"]) {
1st condition will work also if your array contains NSNumbers (not likely in your case as you assign array elements to text property), but will fail if string is not a valid number - in that case intValue will return 0 as well.
2nd condition will work fine if you're sure that your elements are strings and you want to compare exactly with #"0".
Your condition is equivalent to
if ([array objectAtIndex:0])
because == operator has greater priority and evaluates to 0. Comparing array's element to 0 directly also does not make sense as NSArray cannot contain nil objects anyway
It might be easier to get the length of the array first and make sure that it has enough elements and then start accessing the elements themselves.

Boolean inside property list (Simple!)

I'm writing a small application right now and I got problems while reading out a property list...
My exact question is: How can I read out a boolean from the property list? Or better how can I read out this boolean from a NSDictionary?
Thanks, mavrick3.
The objects are stored as NSNumber objects, so to retrieve the BOOL you should use this method:
BOOL myBool = [someNSNumberObject boolValue];
To retrieve from a dictionary do something like this:
BOOl myBool = [[someDictionary objectForKey:#"someKey"] boolValue];
Documentation here: http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/Reference/Reference.html#//apple_ref/occ/instm/NSNumber/boolValue
Try storing the BOOL as a NSNumber ... then adding that to the Dictionary.
A simple example :
BOOL answered = YES;
NSNumber *answeredAsNumber = [NSNumber numberWithBool:answered];
[dict setObject:answeredAsNumber forKey:#"isAnswered"];
BOOL retrievedAnswered = [[dict objectForKey:#"isAnswered"] boolValue];
A BOOL should be stored as a NSNumber and you can access the BOOL value by saying
BOOL myvalue = [aNSNumber boolValue]