Reputation: 583
i am trying to learn json with iOS.
i am trying to implement json data with UITableView
. In my tableview row in Title and subtitle are displaying the values. I can load data in title but when try to load in subtitle, app is getting crashed because in subtitle result that field of json and in that many key-pair value is given. So It can't be possible to display in sub title in tableview.
My question is how can I load subtitle and if key in many key pair value is available to when click on that it gets redirected to other tableview for displaying that data.
My Code:
- (void)viewDidLoad {
[super viewDidLoad];
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://query.yahooapis.com/v1/public/yql?q=select+*+from+weather.forecast+where+woeid%3D1100661&format=json"]];
NSError *error=nil;
id response=[NSJSONSerialization JSONObjectWithData:data options:
NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:&error];
if (error) {
NSLog(@"%@",[error localizedDescription]);
} else {
_query = [response objectForKey:@"query"];
NSLog(@"%@",_query);
_keyArray = [_query allKeys];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_keyArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] ;
}
NSString *key = [_keyArray objectAtIndex:indexPath.row];
//NSString *dictionary = [_query objectForKey:key];
NSString *dictionary = [_query objectForKey:key];
cell.textLabel.text = key;
cell.detailTextLabel.text = dictionary;
return cell;
}
Thanks.
Upvotes: 0
Views: 66
Reputation: 798
Things I've understood from your question and comments, here is my answer step by step...
First I have taken a NSArray
and a NSDictionary
properties in my ViewController.h
class like this.
{
NSArray *_allKeys;
}
@property(nonatomic,strong) NSDictionary *query;
Then in ViewController.m
I have created a setter method for query
property , where I am setting the data into _query
and _allKeys
like this...
-(void)setQuery:(NSDictionary *)query
{
_query = query;
_allKeys = [_query allKeys];
if ([self isViewLoaded]) {
[tableView reloadData];
}
}
Now in UITableView
datasource method cellForRow
, I have updated your code..
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
NSString *key = _allKeys[indexPath.row];
id value = _query[key];
cell.textLabel.text = key;
if ([value isKindOfClass: [NSString class]]) {
cell.accessoryType = UITableViewCellAccessoryNone;
cell.detailTextLabel.text = (NSString*)value;
}
else if ([value isKindOfClass: [NSDictionary class]])
{
cell.detailTextLabel.text = @"More Info";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
else if ([value isKindOfClass: [NSArray class]])
{
cell.detailTextLabel.text = @"Multiple Entries Found";
cell.accessoryType = UITableViewCellAccessoryNone;
// do something show array data with prototype custom cell
}
return cell;
}
And now in UITableView
delegate method didSelect
, I have create a new instance for same ViewController
(We can reuse it because , it has same UI layout), and passing the value of _query
...
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *key = _allKeys[indexPath.row];
id value = _query[key];
if ([value isKindOfClass: [NSDictionary class]])
{
ViewController *nextVC = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
nextVC.query = value;
[self.navigationController pushViewController:nextVC animated:YES];
}
}
Note: I don't want to call that webservice
call in ViewController.m
, whenever I'm instantiating the ViewController
instance . So I put the webservice
code in AppDelegate
didFinishLaunch
method.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://query.yahooapis.com/v1/public/yql?q=select+*+from+weather.forecast+where+woeid%3D1100661&format=json"]];
NSError *error=nil;
id response=[NSJSONSerialization JSONObjectWithData:data options:
NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:&error];
if (error) {
NSLog(@"%@",[error localizedDescription]);
} else {
NSDictionary* _query = [response objectForKey:@"query"];
dispatch_async(dispatch_get_main_queue(), ^{
ViewController *vc = (ViewController*)[(UINavigationController*)self.window.rootViewController topViewController];
vc.query = _query;
});
}
// Override point for customization after application launch.
return YES;
}
It's up to you that where you put this code, but most preferably we should put following code in the previous UIViewController
of your DatashowingViewController
(Mine is ViewController
) and pass the information to ViewController
(like I have done), so that we can reuse the same UIViewController
for showing same result.
I hope this answer will help you achieving your output.
Upvotes: 1