[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance - objective-c

I am trying to parse a Json file into the Table view and I am getting this error
[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance
and the app is crashing. Please help me, I am new to iOS development.
My Code
#implementation ViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
self.title = #"Feeds";
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"http://little-people.blogspot.com/feeds/posts /default?alt=json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
data = [[NSMutableData alloc] init];
NSLog(#"Data Data , %#", data);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
feed = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"Data , %#", feed);
[mainTableView reloadData];
}
- (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 [feed count];
NSLog(#"Data Data , %#", feed);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MainCell"];
}
if (([feed count] - 1) >=indexPath.row) {
cell.textLabel.text = [[feed objectAtIndex:indexPath.row] objectForKey:#"feed"];
cell.detailTextLabel.text = [[feed objectAtIndex:indexPath.row] objectForKey:#"title"];
}
return cell;
}

The problem is that feed is not a NSArray, but a NSDictionary.
Looking at the JSON, you likely want to access this array: [feed objectForKey:#"entry"]

The top level object in your feed is a JSON object, not a JSON array. So the deserialisation gives you an NSDictionary, not an NSArray.

Related

UITableView reload data takes forever

I parse a couple of things via JSON into a table view but I have the problem that the parsing takes about a second (I know this due to the network indicator) but then there is a huge delay until the data appears in the table view.
I tried to place [tableView reloadData]; at a couple of places already but no success.
Here is my code.
I have defined mainThreadQueue and myClassicoAPI as a macro.
- (void)viewDidLoad
{
[super viewDidLoad];
arrayNeuheiten = [[NSArray alloc] init];
arrayArtikelName = [[NSArray alloc] init];
dictionaryNewStuff = [[NSDictionary alloc] init];
[self parseJSONWithURL:myClassicoAPI];
//[self performSelector:#selector(updateTableView) withObject:nil afterDelay:NO];
[neuheietenTable reloadData];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[neuheietenTable reloadData];
}
-(void) updateTableView {
[neuheietenTable reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)numberOfRowsInSection:(NSInteger)section {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//return (self.arrayNeuheiten.count<17)?self.arrayNeuheiten.count : 17;
return MIN(18, arrayNeuheiten.count);
}
-(void) parseJSONWithURL: (NSURL *) jsonURL {
dispatch_async(mainThreadQueue, ^{
NSError *error = nil;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSString *json =[NSString stringWithContentsOfURL:jsonURL encoding:NSJSONWritingPrettyPrinted error:&error];
if (error == nil) {
NSData *jsonData = [json dataUsingEncoding:NSJSONWritingPrettyPrinted];
dictionaryNewStuff = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
if (error == nil) {
dispatch_async(mainThreadQueue, ^{
arrayArtikelName = [[dictionaryNewStuff valueForKey:#"newstuff"] valueForKey:#"Neuheiten"];
arrayNeuheiten = [[dictionaryNewStuff valueForKey:#"newstuff"] valueForKey:#"Neuheiten"];
[neuheietenTable reloadData];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});
} else {
nil;
}
} else {
nil;
}
});
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NeuheitenCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[arrayArtikelName objectAtIndex:indexPath.row] objectForKey:#"name"];
return cell;
}
Thanks in advance
Constantin
You're loading the data synchronous on the mainthread which is bad and blocking the interface.
Try loading your JSON data with NSURLConnection and reload your UITableView in the
(void)connectionDidFinishLoading:(NSURLConnection *)aConnection
method when you're done processing it.
Hello I am bit modify the code with one public url and its work fine. Look at the code which useful to solve your problem:
- (void)viewDidLoad
{
[super viewDidLoad];
arrayNeuheiten = [[NSArray alloc] init];
arrayArtikelName = [[NSArray alloc] init];
dictionaryNewStuff = [[NSDictionary alloc] init];
[neuheietenTable reloadData];
NSURL *url = [NSURL URLWithString:#"http://122.182.14.104:3004/build/product/15.json"];
[self parseJSONWithURL:url];
//[self performSelector:#selector(updateTableView) withObject:nil afterDelay:NO];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)numberOfRowsInSection:(NSInteger)section {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//return (self.arrayNeuheiten.count<17)?self.arrayNeuheiten.count : 17;
return arrayArtikelName.count;
}
-(void) parseJSONWithURL: (NSURL *) jsonURL {
NSError *error = nil;
NSString *json =[NSString stringWithContentsOfURL:jsonURL encoding:NSJSONWritingPrettyPrinted error:&error];
if (error == nil) {
NSData *jsonData = [json dataUsingEncoding:NSJSONWritingPrettyPrinted];
dictionaryNewStuff = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
if (error == nil) {
arrayArtikelName = [dictionaryNewStuff valueForKey:#"attributes"];
// arrayNeuheiten = [[dictionaryNewStuff valueForKey:#"newstuff"] valueForKey:#"Neuheiten"];
[neuheietenTable reloadData];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
} else {
nil;
}
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NeuheitenCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[arrayArtikelName objectAtIndex:indexPath.row] objectForKey:#"name"];
return cell;
}

Facebook JSON feed - __NSArrayM insertObject:atIndex:]: object cannot be nil

I'm trying to parse a Facebook Page Json Feed to a table view and followed this Tutorial
and I'm getting this error: "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSArrayM insertObject:atIndex:]: object cannot be nil'"
Here is my code from my tableview.h:
#import "FBViewController.h"
#interface FBViewController ()
{
NSMutableData *fbdata;
NSMutableArray *array;
}
#end
#implementation FBViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[self fbtableview]setDelegate:self];
[[self fbtableview]setDataSource:self];
array = [[NSMutableArray alloc]init];
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/XXXXXXX/posts?access_token=ACCESS_TOKEN"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
connection = [NSURLConnection connectionWithRequest:request delegate:self];
if (connection) {
fbdata=[[NSMutableData alloc]init];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[fbdata setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[fbdata appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"fail with error");
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSDictionary *allDataDictionary = [NSJSONSerialization JSONObjectWithData:fbdata options:0 error:nil];
NSArray *arraydata = [allDataDictionary objectForKey:#"data"];//objectforkey corresponde ao nome do dicionario
for (NSDictionary *diction in arraydata)
{
NSString *message =[diction objectForKey:#"message"];
[array addObject:message];
[[self fbtableview]reloadData];
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [array count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.text = [array objectAtIndex:indexPath.row];
return cell;
}
#end
Can anyone help me out?
problem is here i think so,
for (NSDictionary *diction in arraydata)
{
NSString *message =[diction objectForKey:#"message"];
[array addObject:message]; //here some value is nil means you are trying to add a nil object to array that's why app getting crashed.
[[self fbtableview]reloadData];
}
}

Access another top-level JSON object with Objective-C

Iam having a hard time accessing another top-level JSON object within my application.
The plan is to load data from Instagram (which works), but not to count the top-level I want.
The JSON document can be found here (http://pastebin.com/0Z4vBjRn) Basically it has three top-level objects: pagination, meta and data (where I want the data bit).
This is my code for now:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Viser "spinner" for å symbolisere nettverkstrafikk.
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// URL til JSON filen
NSURL *newsUrl = [NSURL URLWithString:#"https://api.instagram.com/v1/tags/beer/media/recent?client_id=client_key"];
//URL Requestobjekt for å kontrollere tilkobling
NSURLRequest *newsRequest = [NSURLRequest requestWithURL:newsUrl];
[[NSURLConnection alloc]initWithRequest:newsRequest delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
[rawImages setLength:0];
rawImages = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[rawImages appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
images = [[NSArray alloc]init]; // Updated
images = [NSJSONSerialization JSONObjectWithData:rawImages options:0 error:0];
[self.collectionView reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:#"Feil" message:#"Det har oppstått en feil ved nedlastingen av data. Dobbeltsjekk at du er koblet til internett" delegate:nil cancelButtonTitle:#"Fortsett" otherButtonTitles:nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [images count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCelle *cell = (UICollectionViewCelle *)[collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:#"eksempel.jpg"];
return cell;
}
Obviously the count part won't work (it only returns three). But how could I make it count all the objects within the "data" object?
All help are highly appreciated! I've done my Googling but I can't seem to find exactly what Iam looking.

Update JSON data in tableview properly

Iam having a hard time updating my tableview with new results when the user slides to update (UIRefreshControl). The controller works properly, but the data never gets updated. I've tried to wipe the raw-data variable, and my NSArray that holds all the data, but it doesn't seem to work. Iam new to iPhone programming, so forgive me is this is a dumb question.
If I managed to fixed it, wouldn't it be wrong to remove all the data I've already pulled? Is there a simple way to append changes, considering most of my users will be using 3G/Edge connections. Here's my implementation class for the TableViewController:
#import "Nyhetsfane.h"
#interface Nyhetsfane ()
#end
#implementation Nyhetsfane
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Kaller på slide to update.
[self updateTable];
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(updateTable) forControlEvents:UIControlEventValueChanged];
[refreshControl setAttributedTitle:[[NSAttributedString alloc] initWithString:#"Dra for å oppdatere"]];
self.refreshControl = refreshControl;
}
- (void)updateTable{
// Viser "spinner" for å symbolisere nettverkstrafikk.
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// URL til JSON filen
NSURL *newsUrl = [NSURL URLWithString:#"http://localhost:7192/fadderapp/events.json"];
//URL Requestobjekt for å kontrollere tilkobling
NSURLRequest *newsRequest = [NSURLRequest requestWithURL:newsUrl];
[[NSURLConnection alloc]initWithRequest:newsRequest delegate:self];
[self.tableView reloadData];
[self.refreshControl endRefreshing];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
[newsRawData setLength:0];
newsRawData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[newsRawData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
newsCases = [NSJSONSerialization JSONObjectWithData:newsRawData options:0 error:0];
[self.tableView reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:#"Feil" message:#"Det har oppstått en feil ved nedlastingen av data. Dobbeltsjekk at du er koblet til internett" delegate:nil cancelButtonTitle:#"Fortsett" otherButtonTitles:nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [newsCases count];
}
- (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 = [[newsCases objectAtIndex:indexPath.row]objectForKey:#"navn"];
return cell;
}
...
For all it's worth, here's my JSON feed:
[
{"navn": "Registration", "tidspunkt": "Monday 15:05", "beskrivelse": "Demo!"},
{"navn": "Party!", "tidspunkt": "Monday 19:30", "beskrivelse": "Demo"}
]
Try with this code
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
newCases = [NSArray array];
newsCases = [NSJSONSerialization JSONObjectWithData:newsRawData options:0 error:0];
[self.tableView reloadData];
}
The proper way to update a table view is to call
[self.tableView reloadData];
It should call all its datasource methods again automatically.

Returned web service data not populating tableview

Hey, I cant seem why this code is not working? I am trying to add my returned data from a web service into the uitableview, however failing miserably. The table shows up blank everytime. It seems it doesnt like the cellForRowAtIndexPath method. But honestly I am not sure. I cant spot it for nothing. Please help. Thanks!
#import "RSSTableViewController.h"
#implementation RSSTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
if (self = [super initWithStyle:style]) {
songs = [[NSMutableArray alloc] init];
}
return self;
}
- (void)loadSongs
{
[songs removeAllObjects];
[[self tableView] reloadData];
// Construct the web service URL
NSURL *url =[NSURL URLWithString:#"http://localhost/get_params"];
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:30];
if (connectionInProgress) {
[connectionInProgress cancel];
[connectionInProgress release];
}
[xmlData release];
xmlData = [[NSMutableData alloc] init];
connectionInProgress = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self loadSongs];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[xmlData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
NSString *responseString = [[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding];
songs = [responseString componentsSeparatedByString:#","];
newSongs = [[NSMutableArray alloc] init];
for(int i=0; i < [songs count]; i++) {
[newSongs addObject:[songs:i]]);
}
[songs autorelease];
[[self tableView] reloadData];
//
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
[connectionInProgress release];
connectionInProgress = nil;
[xmlData release];
xmlData = nil;
NSString *errorString = [NSString stringWithFormat:#"Fetch failed: %#",
[error localizedDescription]];
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:errorString
delegate:nil
cancelButtonTitle:#"OK"
destructiveButtonTitle:nil
otherButtonTitles:nil];
[actionSheet showInView:[[self view] window]];
[actionSheet autorelease];
[[self tableView] reloadData];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [newSongs count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"UITableViewCell"] autorelease];
}
[[cell textLabel] setText:[newSongs objectAtIndex:[indexPath row]]];
return cell;
}
#end
It appears you're ignoring warning messages, which is a no-no in Objective-C. The following code can't possibly work:
[newSongs addObject:[songs:i]]
What you probably meant to write was something like this:
[newSongs addObject:[songs objectAtIndex:i]]
But instead of doing all this:
newSongs = [[NSMutableArray alloc] init];
for(int i=0; i < [songs count]; i++) {
[newSongs addObject:[songs:i]]);
}
why not just do this?
newSongs = [songs mutableCopy];