Reputation: 75
I have a pickerview with which I would want to display values using JSON parsing. I am aware some questions on the site already tackle parsing and pickerview but mine is slightly different in regards to the structure of my json file. Here's a sample of the json file.
[
{
"model":"juice",
"id" :
[
{
"version": "version01"
},
{
"version": "version02"
}
]
},
{
"model":"cream",
"id" :
[
{
"version": "cream01"
},
{
"version": "cream02"
}
]
}
]
and my .m file
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL * serverhost = [NSURL URLWithString:@"http://my.json"];
NSError *error;
NSData * Data = [NSData dataWithContentsOfURL: serverhost];
self.modelsArray= [NSJSONSerialization JSONObjectWithData:Data options:NSJSONReadingAllowFragments error:&error];
NSLog(@"%@", modelsArray);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
if (component == departments)
return [self.modelsArray count];
return [self.versionsArray count];
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == departments)
return [[self.modelsArray objectAtIndex:row]objectForKey:@"model"];
return [[[self.versionsArray objectAtIndex:row]objectForKey:@"model"]objectForKey:@"version"];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component
{
if (component == departments)
{
NSString * selectedRow = [[self.modelsArray objectAtIndex: row] valueForKey:@"version"];
NSArray * array = [sybreDepts objectForKey:selectedRow];
self.
}
}
@end
Basically when I select a model i.e juice or cream on the first column the second column should display its contents with key being 'versions' thus when juice is selected "version01" and "version02" should be displayed on the second column.
In regards to the line return [[[self.versionsArray objectAtIndex:row]objectForKey:@"model"]objectForKey:@"version"];
I don't believe it was executed correctly as I get an error
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0xa18c450' . Any suggestions ? Thanks
Upvotes: 2
Views: 1441
Reputation: 78855
If you nicely indent your JSON data and look at it:
[
{
"model": "juice",
"id" : [
{
"version": "version01"
},
{
"version": "version02"
}
]
},
....
then you'll see that it has the following structure (from the outer to the inner elements):
So if you want to access the second version of the first model, you have to write something like this:
NSArray* versionsArray = [[self.modelsArray objectAtIndex:modelRow] objectForKey:@"id"];
NSString* versionName = [[versionArray objectAtIndex: versionRow] objectForKey:@"version"];
In your code, I can't see where self.versionArray
is ever assigned a value. And as I've pointed out in my comment, the following line doesn't match the JSON data structure:
return [[[self.versionsArray objectAtIndex:row]objectForKey:@"model"]objectForKey:@"version"];
The part:
[[self.versionsArray objectAtIndex:row]objectForKey:@"model"]
will return a NSString
instance. And if you then call objectForKey:@"version"
, you'll get the unrecognized selector sent error.
Update:
The changed code could look like this:
.h file:
NSInteger modelRow;
.m file:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == departments)
return [self.modelsArray count];
NSArray* versionsArray = [[self.modelsArray objectAtIndex:modelRow] objectForKey:@"id"];
return [versionsArray count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == departments)
return [[self.modelsArray objectAtIndex:row]objectForKey:@"model"];
NSArray* versionsArray = [[self.modelsArray objectAtIndex:modelRow] objectForKey:@"id"];
return [[versionsArray objectAtIndex:row] objectForKey:@"version"];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component
{
if (component == departments)
{
modelRow = row;
[pickerView reloadComponent:1];
}
}
@end
Upvotes: 2