Reputation: 894
I'm experiencing a problem with my code but I'm not sure why it's doing this. It's just giving me an error saying JSON Error. The UITableView never gets filled with anything. I'm not very experienced with iOS, so any help is appreciated.
//
// ViewController.m
// Westmount Procrastinator
//
// Created by Saleem on 10/25/13.
// Copyright (c) 2013 Saleem Al-Zanoon. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIWebView *webView;
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *fullURL = @"********";
NSURL *url2 = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url2];
[_webView loadRequest:requestObj];
self.title = @"News";
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:@"****************"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self]; // NSString * urlString = [NSString stringWithFormat:@"http://salespharma.net/westmount/get_all_products.php"];
// NSURL * url = [NSURL URLWithString:urlString];
// NSData * data = [NSData dataWithContentsOfURL:url];
// NSError * error;
// NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
// NSLog(@"%@",json);
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
data = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSArray *responseDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:NULL];
//news = [responseDict objectAtIndex:0];
// [mainTableView reloadData];
if ([responseDict isKindOfClass:[NSArray class]]) {
news = responseDict;
[mainTableView reloadData];
} else {
// Looks like here is some part of the problem but I don't know why.
NSLog(@"JSON Error.");
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Could not contact server!" delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
[errorView show];
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"The download could not complete - please make sure you're connected to either 3G or Wi-Fi." delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [news count];
}
NSString *_getString(id obj)
{
return [obj isKindOfClass:[NSString class]] ? obj : nil;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];
}
cell.textLabel.text = _getString([[news objectAtIndex:indexPath.row] objectForKey:@"Issue"]);
cell.detailTextLabel.text = _getString([[news objectAtIndex:indexPath.row] objectForKey:@"Name"]);
return cell;
}
@end
How the JSON looks on the internet:
{
"Issues":[
{
"Issue":"2",
"Link":"google.com",
"Name":"Ios Test"
},
{
"Issue":"3",
"Link":"Yahoo",
"Name":"iOS test 2"
}
],
"success":1
}
Edit: sorry for not being clear in my question, The app does not crash but fails to load the data into the database in the log it puts this up:
2013-10-26 10:26:41.670 Westmount Procrastinator[2490:70b] JSON Error.
2013-10-26 10:26:41.671 Westmount Procrastinator[2490:70b] Server Data:
{"Issues":[{"Issue":"2","Link":"google.com","Name":"Ios Test"}],"success":1}
The goal of the application to contact a database download a list of Issues of a newspaper then list them in the list view.. Then allowing the user to click on the issues and download them.
Edit I added more to the JSON to help explain.
Upvotes: 1
Views: 2353
Reputation: 5654
Issues is an array of dictionaries, so you should ask for the dictionary at the indexpath.row
, then use objectForKey
to pull the appropriate value from that dictionary.
NSDictionary *myDict = @{@"Issues": @[@{@"Issue": @"2",
@"Link": @"google.com",
@"Name": @"Ios Test"},
@{@"Issue": @"3",
@"Link": @"Yahoo",
@"Name": @"iOS test 2"}],
@"success": @"1"};
NSArray *issues = [myDict objectForKey:@"Issues"];
[issues enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"Issue: %@ Link: %@ Name: %@", [obj objectForKey:@"Issue"], [obj objectForKey:@"Link"], [obj objectForKey:@"Name"]);
}];
Will return:
2013-10-26 16:42:43.572 Jsontest[43803:303] Issue: 2 Link: google.com Name: Ios Test
2013-10-26 16:42:43.573 Jsontest[43803:303] Issue: 3 Link: Yahoo Name: iOS test 2
Upvotes: 0
Reputation: 38152
From your sample JSON structure it does not appear to be a NSArray. It is NSDictionary instead. So, while you are parsing JSON data save it in NSDictionary and not in NSArray. Also, change your IF condition afterwards.
Importantly, if your tableview is reading data from an NSArray of NSDictionaries then I would say put this NSDictionary into an NSArray and pass it to table view. Also, check from server side what is the output in case they are multiple dictionaries in which you need to handle accordingly. So essentially there are couple of more lines you need to induce here or else ask data provider (server side) to send NSArray in all cases.
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:NULL];
if ([responseDict isKindOfClass:[NSDictionary class]]) {
NSArray *tableArray = [NSArray arrayWithArray:responseDict[@"Issues"]];
}
Now use tableArray to populate your table.
Upvotes: 3