Objective c Setting picker value from NSDictionary - iphone

Another, probably simple problem that, having tried for a good few hours now I'm pretty stumped on. Simply, I want to set the value of a picker from a NSDictionary, I don't mind! Every way I have tried pretty much gives me the warning Passing argument 1 of selectRow inComponent animated' makes integer from pointer witout a cast. Which makes sense, though I seem to be failing miserable at fixing it! Any help would be greatly appreciated! Snippet of code below...
NSArray *myValue = [parsedJson objectForKey:#"Details"];
NSEnumerator *myEnumerator = [myValue objectEnumerator];
NSDictionary* myItem;
int i = 0;
while (myItem = (NSDictionary*)[myEnumerator nextObject])
{
[myPickerView selectRow:[myItem objectForKey:#"Value"] inComponent:i animated:YES];
i++;
}

Assuming your value responds to intValue message (e.g. number is stored in NSNumber or NSString) then the following should work:
[myPickerView selectRow:[[myItem objectForKey:#"Value"] intValue]
inComponent:i animated:YES];

The selectRow parameter is expecting an integer, try this:
[myPickerView selectRow:[[myItem objectForKey:#"Value"] integerValue] inComponent:i animated:YES];

Related

Xcode Gives Strange Output From NSArray

When I run this code, the output is some 1084848 to the console. I can't figure out why such odd output... here is the code.
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] init];
int someNumber = 3;
[array addObject:[NSNumber numberWithInt:someNumber]];
NSLog(#"%i" , [array objectAtIndex:0]);
[pool drain];
return 0;
}
the "%i" format specifier expects an integer, not an Object.
Try NSLog(#"%i" , [[array objectAtIndex:0] intValue]);
XCode is probably giving you a warning on this line: something like "Conversion specifies type 'int', but argument has type 'id'".
Here's the pseudocode of your program:
//
// Inside of your main function....
//
// Set up the Autorelease pool and then create an array
//
// Declare an int
//
// Add the int to an array, while wrapping it in an NSNumber
//
// Log the value of the first object in the array, using the int formatter
//
// Clean up and return
//
You are logging the first object in the array, but NSArray cannot hold a primitive that's not wrapped in an Objective-C object.
To better understand your code, try changing these lines of code:
int someNumber = 3;
[array addObject:[NSNumber numberWithInt:someNumber]];
Expand them a little. Try this:
int someNumber = 3;
NSNumber *aNumber = [NSNumber numberWithInt:someNumber];
[array addObject:aNumber];
So, you've correctly wrapped the int in an NSNumber, but you're not unwrapping it. You need to ask your NSNumber for the int that it holds like so:
[[array objectAtIndex:0] intValue];
Or, to do the logging in one line:
NSLog(#"%i" , [[array objectAtIndex:0] intValue]);
The characters "%i" is called a "formatter". Different kinds of values require different formatters. When you are using an Objective-C object, you use "%#". For an NSInteger or int, you'd use %i. For a float, you'd use "%f". The point is that you need to either unwrap that number, or use the Objective-C formatter for strings.
A quick note about that weird value you were getting earlier: That's a memory address in RAM. It's the closest thing you're going to get when you use an incorrect formatter. In some cases, using the wrong formatter will cause an EXC_BAD_ACCESS. You were "lucky" and got a weird value instead of a dead program. I suggest learning about strings and formatters before you move on. It will make your life a lot easier.
When you use %i for integer values then you should give arguments as integer as below
NSLog(#"%i" , [[array objectAtIndex:0] intValue]);
But when you want object to be displayed then you must use %# which identifies object in general case as below:
NSLog(#"%#", array);

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.

Adding Objects to an Objective C Array at Index

I have a synthesized NSMutableArray - theResultArray . I want to insert NSNumber or NSInteger objects at specific indexes (0-49). For some reason I can never get any values to stick in my array. Every index returns nil or 0.
NSInteger timeNum = time;
[theResultArray insertObject:[NSNumber numberWithInt:timeNum] atIndex:rightIndex];
NSLog(#"The right index is :%i", rightIndex);
NSLog(#"The attempted insert time :%i", time);
NSNumber *testNum = [theResultArray objectAtIndex:rightIndex];
NSLog(#"The result of time insert is:%i", [testNum intValue]);
I alloc-init theResultsArray in viewDidLoad. Time is an integer. I have been trying different combinations of the code above to no avail.
The console outputs this:
StateOutlineFlashCards[20389:20b] The right index is :20
StateOutlineFlashCards[20389:20b] The attempted insert time :8
StateOutlineFlashCards[20389:20b] The result of time insert is:0
Unless I'm misreading, aren't you inserting an NSInteger, but then trying to take out an NSNumber? Those are two completely different data types. It doesn't surprise me that you're getting odd results.
Furthermore, NSInteger isn't an object, so you can't stick it into an array. You probably want to be allocating an NSNumber with that integer and putting that in.
Try something like: [theResultArray addObject:[NSNumber numberWithInteger:timeNum] atIndex:rightIndex];
Likewise, when you retrieve the value, you'll need to unbox it:
NSLog(#"The result of time insert is:%i", [testNum integerValue])`;
Likewise, when you retrieve the value, you'll need to unbox it:
Frankly, I'm a little surprised that this even compiles.
You need to allocate memory for the array in your init or viewDidLoad method, otherwise you won't be able to store anything at all.
If you do this:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
myMutableArrayName = [[NSMutableArray alloc] init];
}
return self;
}
Or this:
- (void)viewDidLoad {
[super viewDidLoad];
myMutableArrayName = [[NSMutableArray alloc] init];
}
It should work for you.
As for storing integers in an NSMutableArray, I took a simple but somewhat "hackish" approach recently. I store them as strings. When I put them in I use:
[NSString stringWithFormat:#"%d", myInteger];
And when I take them out I convert with:
[[myArray objectAtIndex:2] intValue];
It was really easy to implement but depending on the context you may want to use another way.
NSInteger timeNum = time;
What is that for? What is "time"?
[theResultArray addObject:timeNum atIndex:rightIndex];
There is no method -addObject:atIndex:. It is -insertObject:atIndex:. Why are you inserting at "rightIndex" anyway? Why not just use -addObject:?
//[theResultArray replaceObjectAtIndex:rightIndex withObject:[NSNumber numberWithInt:timeNum]];
What is that and why is it commented out?
NSLog(#"The right index is :%i", rightIndex);
NSLog(#"The attempted insert time :%i", time);
NSNumber *testNum = [theResultArray objectAtIndex:rightIndex];
//int reso = [testNum integerValue];
NSLog(#"The result of time insert is:%i", testNum);
What are you trying to do?