I am newbie for iPhone application. I am learning how to get the JSON data and parse it and show it in table in iPhone. For that I am going through this video.
I made this with xib file and its working perfectly.
What I was trying is do this with Storyboard. I did same thing as I did for Stoaryboard, however the execution is getting break at below line.
cell.textLabel.text = [[news objectAtIndex:indexPath.row] objectForKey:#"title"];
Code I have is
-(UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"i m here 1");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
NSLog(#"i m here 2");
if (cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
NSLog(#"i m here 3");
}
NSLog(#"i m here 4");
cell.textLabel.text = [[news objectAtIndex:indexPath.row] objectForKey:#"title"];
// cell.textLabel.text = #"dadsf ad";
NSLog(#"i m here 5");
return cell;
}
In NSLog, I get output till i m here 4.
When I comment cell.textLabel.text = [[news objectAtIndex and uncomment cell.textLabel.text = #"dadsf ad";, it works and I see dadsf ad in iPhone.
// cell.textLabel.text = [[news objectAtIndex:indexPath.row] objectForKey:#"title"];
cell.textLabel.text = #"dadsf ad";
When I run with cell.textLabel.text = [[news objectAt, I get below screen.
Note:
I also went to simulator and did Reset Content and Setting, still facing same problem. Any idea why?
Update 1
I activate the NSZombieEnabled and run the code. I get in NSLOG as
JSONNewsStoryBoard[19389:11303] i m here 4
2013-01-06 11:26:15.327 JSONNewsStoryBoard[19389:11303] *** -[CFArray objectAtIndex:]: message sent to deallocated instance 0x7497040
Below is the screen shot.
Update 2 - ANSWER
I tried adding NSLog(#"checking news count %d", [news count]); in cellForRowAtIndexPath and I got same problem. Means news was null.
So I added
news = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
in cellForRowAtIndexPath and it worked. :) :)
It appears that the news object has been deallocated sometime before objectAtIndex: is called on it, and this probably has something to do with the way interface builder and storyboard take over control of the objects you give them. Try checking if news is equal to nil at various points in your code. You may have to instantiate news at a different point in time.
Related
I'm working on information retrieval where in the latest information in on top of UITableView. The code goes like this.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
LoanModel* loan = _feed.products[indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" ];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:#"Cell"];
}
NSString *myString = [NSString stringWithFormat:#"%#",[loan name]];
NSArray *myWords = [myString componentsSeparatedByString:#","];
NSMutableArray *reversed = [NSMutableArray arrayWithCapacity:[myWords count]];
NSEnumerator *enumerator = [myWords reverseObjectEnumerator];
for (id element in enumerator) {
[reversed addObject:element];
}
NSMutableString *reverseString = [reversed componentsJoinedByString:#","];
cell.textLabel.text = reverseString;
return cell;
}
I'm getting the JSON object which contain two fields cid and name respectively. I'm showing only the name is tableview. But I want to show it in reverse i,e last update should show at first. But above code showing the content in reverse. IF "hello" is the content, then it shows "olleh". Please suggest me how to get the UITableView in reverse list. I'm a newbie to iOS.
If you want to have the reversed order of cells / objects they represent, you have to change
LoanModel* loan = _feed.products[indexPath.row];
to
LoanModel* loan = _feed.products[_feed.products.count - 1 - indexPath.row];
assuming that _feed.products is an NSArray.
The array you are using to display the the data in tableView, you'll need to reverse that and then display the data in tableView
NSArray* reversed = [[myArray reverseObjectEnumerator] allObjects];
you can use this to make your array objects order in reverse.
Try This:
NSArray* reversedArray = [[myWords reverseObjectEnumerator] allObjects];
The HDLogOnViewController passes two variables to the HDDomicileViewController in the
tableview:didSelectRowAtIndexPath method of HDLogOnViewController.
The app crashes with a EXC BAD ACCESS error after the viewDidLoad method of the HDDomicileViewController. The variables are verified correct in HDDomicileViewController.
I have enabled Zombies with no help. When I enable Guard Malloc the app runs normally. In the output view of XCode there is no indication of what is causing the error. I have researched many EXC BAD ACCESS threads here and have tried using properties instead of instance variables. I have used four if statements instead of if else if. When doing this the app would run normally with only one if statement but would crash with more than one. Also, with the four if statements I could comment out the statements of each and it would crash, making it appear the problem was in the if condition.
How can I discover what is causing the error?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellLabel = [NSString stringWithString:[[[HDLogOnStore sharedStore] cellTitleLabels] objectAtIndex:[indexPath row]]];
if ([cellLabel isEqualToString:#"Domicile"]) {
tableViewArray = [[HDLogOnStore sharedStore] domiciles];
tableViewArrayName = #"domiciles";
NSLog(#"indexPath row is %i", [indexPath row]);
NSLog(#"array name is %#", [[[HDLogOnStore sharedStore] cellTitleLabels] objectAtIndex:[indexPath row]]);
}
else if ([cellLabel isEqualToString:#"Position"]) {
tableViewArray = [[HDLogOnStore sharedStore] positions];
tableViewArrayName = #"positions";
NSLog(#"indexPath row is %i", [indexPath row]);
NSLog(#"array name is %#", [[[HDLogOnStore sharedStore] cellTitleLabels] objectAtIndex:[indexPath row]]);
}
else if ([cellLabel isEqualToString:#"BidRound"]) {
tableViewArray = [[HDLogOnStore sharedStore] bidRounds];
tableViewArrayName = #"bidRounds";
NSLog(#"indexPath row is %i", [indexPath row]);
NSLog(#"array name is %#", [[[HDLogOnStore sharedStore] cellTitleLabels] objectAtIndex:[indexPath row]]);
}
else if ([cellLabel isEqualToString:#"Month"]) {
tableViewArray = [[HDLogOnStore sharedStore] months];
tableViewArrayName = #"months";
NSLog(#"indexPath row is %i", [indexPath row]);
NSLog(#"array name is %#", [[[HDLogOnStore sharedStore] cellTitleLabels] objectAtIndex:[indexPath row]]);
}
HDDomicileViewController *domicileViewController = [[HDDomicileViewController alloc]init];
[domicileViewController setSelectedArray:tableViewArray];
[domicileViewController setSelectedArrayName:tableViewArrayName];
[self.navigationController pushViewController:domicileViewController animated:YES];
}
I began getting inconsistent behavior so I went back to reading more posts here.
I solved the problem by following a suggestion to correct all errors found after analyzing the project. I corrected a few seemingly unrelated errors such as "value stored to 'pairing' during it's initialization is never read". I am not sure if this directly solved the problem but somewhere in the process the problem went away.
FYI
The app was crashing after the viewDidLoad method and before the viewWillAppear method. Step by step debugging led me to machine code which I know nothing about.
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"selectedArray count is %i",[selectedArray count]);
NSLog(#"selectedArray name is %#",selectedArrayName);
NSLog(#"checkedRowMonth is %i",[[HDLogOnStore sharedStore]checkedRowMonth]);
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
UITableView only shows data from JSON array when I scroll up and down. When I load the table view it shows cells but they are blank and as I scroll up and down it then starts showing the data.
How do I show the cells with data without scrolling?
- (void)requestFinished:(ASIHTTPRequest *)request
{
if (request.responseStatusCode == 400) {
NSLog( #"Code already used");
} else if (request.responseStatusCode == 403) {
NSLog( #"Code already used");
} else if (request.responseStatusCode == 200) {
NSLog(#"%#",[request responseString]);
NSString *response = [request responseString];
const char *convert = [response UTF8String];
NSString *responseString = [NSString stringWithUTF8String:convert];
responseArray = [responseString JSONValue];
Nrows = [responseArray count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *dict = [responseArray objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [dict objectForKey:#"allfeeds"];
cell.textLabel.adjustsFontSizeToFitWidth = YES;
cell.textLabel.font = [UIFont systemFontOfSize:12];
cell.textLabel.minimumFontSize = 10;
cell.textLabel.numberOfLines = 4;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.text = [dict objectForKey:#"allfeeds2"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
When you finish your request and you set the array, make sure to call [self.tableView reloadData];
For performance and animation purposes, table views don't reload their data when the source changes.
Instead of starting the request asynchronously (non-blocking)
[request startAsynchronously];
Try doing it synchronously (blocking)
[request startSynchronously];
I had a similar issue and got my answer at the Apple's Developer Forums a while ago, this solved my problem:
From what you've described, I'd guess the problem is more likely to be in cellForRowAtIndexPath or wherever you do the actual configuration of a cell than in the code you've posted. A problem like yours can happen when dequeueReusableCellWithIdentifier gives you back an existing cell, but you don't reset its existing state completely.
The full question and answers can be found here (requires login): https://devforums.apple.com/message/502483#502483
These problems are usually caused by the UITableView cache, that dequeues his available cached UITableViewCell with the same CellIdentifier (in your case - #"Cell").
Try creating a cell identifier for each and everyone of your table's cells. You can create this variance using the NSIndexPath param in the following way :
NSString* cellIdentifier = [NSString stringWithFormat:#"Cell%d",indexPath.row];
That of course, under the assumption you're not changing the content of your cells after you load the data.
So I have a UITableView, and I populate the tableview with data from a .plist. This has been working fine for me until today, when I tried to do the same and I can't get the numberOfRowsInSection, method to work. Here is my code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if...
else if (segmentOptions == exchange){
NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:section]]];
return [array count];
}
//Else
return contentArray.count;
}
So in that code, everytime I run it, the code crashs. But, I use basiacally the same code to set the tableview text and that works fine:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if...
else if (segmentOptions == exchange) {
NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:indexPath.section]]];
cell.textLabel.text = [array objectAtIndex:indexPath.row];
}
return cell;
}
And that code works fine, which is why I'm so confused. When I set the number of rows to return to a specific number, and run the rest of the code, everything works fine. So I'm really lost. Thands in advance
UPDATE
I tried it with the proper count notation, return [array count];, and I still get the same crash and the same console output.
First, count is not a property so you should not be using dot syntax to access it.
I would suggest changing your code so that you are not accessing the count method like a property.
Second,
Test to see if your array is nil and that it is even an array.
Third,
Post the actual complete stack trace.
Break it down and debug, if console message is not being helpful. It helps sometimes, specially when it's late. i.e.
// NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:section]]];
NSLog(#"%d", section);
id objAtIndex = [listOfExchanges objectAtIndex:section];
NSLog(#"%#", listOfExchanges);
NSLog(#"%#", objAtIndex);
id objForKey = [exchangeDictionary objectForKey:objAtIndex];
NSLog(#"%#", exchangeDictionary);
NSLog(#"%#", objForKey);
Try this:
[array count]
count is not a property, it is a method you run on the array.
I have a problem with table view in iphone .. i can't figure out why it crashes everytime
will here is the code
- (void)viewDidLoad
{
[self checkAndCreatePList];
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:pListPath];
self.animals = [plistDict objectForKey:#"Animals"];
[super viewDidLoad];
}
-(UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath
{
static NSString *SimpleTableIdentifier =#"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if(cell== nil){
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SimpleTableIdentifier]autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [animals objectAtIndex:row];
return cell;
}
it's crashes at the line
cell.textLabel.text = [animals objectAtIndex:row];
and tells me that
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance
The Animals key in your plist refers to a dictionary, not an array. Dictionaries don't have a guaranteed order, so asking for an object at a particular index doesn't make sense.
In addition to this, you have a memory leak - plistDict is allocated but never released. Have you run the static analyser over your code?
[plistDict objectForKey:#"Animals"];
is returning a Dictionary not an Array like you are expecting. You need to check out your plist file to see if the data is correct.
the error seems that you are calling objectAtIndex on a NSDictionary object at line cell.textLabel.text = [animals objectAtIndex:row]; check what does animal contains at run time. For this use NSLog before this line. NSLog(#"%#",animals);
Looks like animals is some dictionary and you are calling objectAtIndex: method on it. objectAtIndex: is NSArray method.