Tableview doesn't fire cellForRowtIndexPath method - iphone

My situation:
I've got datasource and delegate connect in the storyboard
I've got for my UITableViewCell and identifier and also in code defined, etc.
I've got the array with data for my UITableView, in debug my data array is filled in viewDidload method
So everything seems right till I arrive to cellForRowIndexPath and numberOfRowsInSection. It doesn't go into the methods. When I
run further, debug is complete, don't get any faults, only a black
UITableView i get with nothing in. Really strange cus my array is
filled with data and everything is connected as it should be.
Some help is needed, i'm searching for days now!
If code is needed to help, ask me.
My code:
m.file:
#import "DagprogrammaDetailViewController.h"
#interface DagprogrammaDetailViewController ()
#end
#implementation DagprogrammaDetailViewController
{
NSMutableArray *DagprogrammaDetail;
}
#synthesize menuNaam;
#synthesize tableDagprogrammaDetail;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = menuNaam;
NSArray *dagarray = [menuNaam componentsSeparatedByString:#" "];
NSString *plaatsString = [dagarray objectAtIndex:1];
plaatsString = [plaatsString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
//object ophalen
NSMutableString *urlString = [NSMutableString stringWithFormat:#"http://zesdaagse.mobi-app.be/WCFUrl/MobileService.svc/GetDagprogramma"];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSMutableArray *id = [NSMutableArray array];
for(NSDictionary *item in json)
{
[id addObject:[item objectForKey:#"id"]];
}
int plaats = [plaatsString intValue];
plaats -= 1;
//id van de dag ophalen
NSString *idDagprogramma = [id objectAtIndex:plaats];
urlString = [NSMutableString stringWithFormat:#"http://zesdaagse.mobi-app.be/WCFUrl/MobileService.svc/GetDagprogrammaWedstrijden?id="];
[urlString appendString:[NSString stringWithFormat:#"%#",idDagprogramma]];
url = [NSURL URLWithString:urlString];
data = [NSData dataWithContentsOfURL:url];
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSMutableArray *idWedstrijdDagprogramma = [NSMutableArray array];
NSMutableArray *naam = [NSMutableArray array];
NSMutableArray *uur = [NSMutableArray array];
for(NSDictionary *item in json)
{
[idWedstrijdDagprogramma addObject:[item objectForKey:#"id"]];
[naam addObject:[item objectForKey:#"naam"]];
[uur addObject:[item objectForKey:#"uur"]];
}
DagprogrammaDetail = [NSMutableArray arrayWithObjects: nil];
for(int i = 0; i < json.count; i ++)
{
NSMutableString *lijn =[NSMutableString stringWithFormat:#"%#", [naam objectAtIndex:i]];
[lijn appendString:[NSMutableString stringWithFormat:#"%s", "\t \t"]];
[lijn appendString:[NSMutableString stringWithFormat:#"%#", [uur objectAtIndex:i]]];
[DagprogrammaDetail addObject:lijn];
}
}
//methode om aantal items te weten van de array
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [DagprogrammaDetail count];
}
//methode om een item aan een index te koppelen en zichtbaar te maken
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"MenuDetailCell";
UITableViewCell *cell = [self.tableDagprogrammaDetail dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.numberOfLines = 1;
cell.textLabel.text = [DagprogrammaDetail objectAtIndex:indexPath.row];
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

I'm very confused right know, so you know how to fix it? Cus in other
view controllers it works fine and it's same code and methods. What
should i do?
Calm Down and Recheck your Code again. I guaranteed that it'll be some silly mistake. It may happens to anyone when you are frustrated.
Things you can do :
1) NSLog your numberOfRowsInSection. Note that , If it's "0" then your cellForRowAtIndexPath is never going to be called.
2) If you are using your UITableView inside some UIView then you should add :
[self.view addSubview:table];
3) Don't Forget to include :
#interface yourViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>

I Just Changed Little-bit in ViedDidLoad and its working fine
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = menuNaam;
NSArray *dagarray = [menuNaam componentsSeparatedByString:#" "];
NSString *plaatsString = [dagarray objectAtIndex:1];
plaatsString = [plaatsString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
//object ophalen
NSMutableString *urlString = [NSMutableString stringWithFormat:#"http://zesdaagse.mobi-app.be/WCFUrl/MobileService.svc/GetDagprogramma"];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSMutableArray *idss = [[NSMutableArray alloc]init];;
NSLog(#"Json Data =%#",json);
for(NSDictionary *item in json)
{
[idss addObject:[item objectForKey:#"id"]];
}
int plaats = [plaatsString intValue];
plaats -= 1;
//id van de dag ophalen
NSString *idDagprogramma = [idss objectAtIndex:0];
urlString = [NSMutableString stringWithFormat:#"http://zesdaagse.mobi-app.be/WCFUrl/MobileService.svc/GetDagprogrammaWedstrijden?id="];
[urlString appendString:[NSString stringWithFormat:#"%#",idDagprogramma]];
url = [NSURL URLWithString:urlString];
data = [NSData dataWithContentsOfURL:url];
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSMutableArray *idWedstrijdDagprogramma = [NSMutableArray array];
NSMutableArray *naam = [NSMutableArray array];
NSMutableArray *uur = [NSMutableArray array];
for(NSDictionary *item in json)
{
[idWedstrijdDagprogramma addObject:[item objectForKey:#"id"]];
[naam addObject:[item objectForKey:#"naam"]];
[uur addObject:[item objectForKey:#"uur"]];
}
DagprogrammaDetail = [[NSMutableArray alloc]init];
for(int i = 0; i < json.count; i ++)
{
NSMutableString *lijn =[NSMutableString stringWithFormat:#"%#", [naam objectAtIndex:i]];
[lijn appendString:[NSMutableString stringWithFormat:#"%s", "\t \t"]];
[lijn appendString:[NSMutableString stringWithFormat:#"%#", [uur objectAtIndex:i]]];
[DagprogrammaDetail addObject:lijn];
}
}
Download my project Here
Link: http://www.4shared.com/zip/FI1HJV1c/DagprogrammaDetail.html

There is no way for us knowing what is going on if you won't post your full code. Obviously you missed something. Follow this step by step tutorial against your code to find where your problem hides.

I think your problem is with UITableViewDataSource protocol. There is method called :
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
You don't have to implement this method, because by default it returns 0. So if you implement this method and this method returns 0, you got problem. As you don't have any section, your datasource methods to create a row never gets called because you don't have any section in your tableview.
To make it work, either you don't implement
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
method at all, or it has to return at least 1.

Related

How to display array of JSON values in custom tableView cells

I want to pass values inside for(NSDictionary *jsonDictionary in myJsonArray) which I get in NSLog to [array addObject:[[SaveList alloc] initWithEmail:email withPhone:phone withDate:date withName:name]];
Code is here
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSError *error = nil;
NSURL *url = [NSURL URLWithString:#" http:// Some url "];
NSString *json = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&error];
NSLog(#"\n\n JSON : %#, \n Error: %#", json, error);
if(!error)
{
NSData *jsonData = [json dataUsingEncoding:NSASCIIStringEncoding];
NSArray *myJsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
// NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
for(NSDictionary *jsonDictionary in myJsonArray)
{
NSLog(#"JSON Dictionary = %#", jsonDictionary);
NSString *name = jsonDictionary[#"Name"];
NSString *date = jsonDictionary[#"Date"];
NSString *email = jsonDictionary[#"Email"];
NSString *phone = jsonDictionary[#"Phone"];
NSLog(#"Name = %#", name);
NSLog(#"Date = %#", date);
NSLog(#"Email = %#", email);
NSLog(#"Phone = %#", phone);
}
}
});
//Table implementation
array = [[NSMutableArray alloc]init];
//**Get email, phone, date, name here**
[array addObject:[[SaveList alloc] initWithEmail:email withPhone:phone withDate:date withName:name]];
self.tableView.dataSource = self;
self.tableView.delegate = self;
Why don't you add the objects as you receive them? Since this block of code will be executed asynchronously you could prepare your array, set your tableview and then execute the block where you fill your array and refresh the tableview.
Something like this:
// Prepare your array
array = [NSMutableArray arrayWithCapacity:0];
// Set your tableview's datasource & delegate
self.tableView.dataSource = self;
self.tableView.delegate = self;
// Fetch data asynchronously
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSError *error = nil;
NSURL *url = [NSURL URLWithString:#" http:// Some url "];
NSString *json = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&error];
NSLog(#"\n\n JSON : %#, \n Error: %#", json, error);
if(!error)
{
NSData *jsonData = [json dataUsingEncoding:NSASCIIStringEncoding];
NSArray *myJsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:myJsonArray.count];
for(NSDictionary *jsonDictionary in myJsonArray)
{
NSString *name = jsonDictionary[#"Name"];
NSString *date = jsonDictionary[#"Date"];
NSString *email = jsonDictionary[#"Email"];
NSString *phone = jsonDictionary[#"Phone"];
//**Get email, phone, date, name here**
[tmp addObject:[[SaveList alloc] initWithEmail:email
withPhone:phone
withDate:date
withName:name]];
}
// Reload your tableview
dispatch_sync(dispatch_get_main_queue(), ^{
array = tmp; // Or add them to your datasource array, whatever suits you...
[self.tableView reloadData];
});
}
});
set number of rows
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
[array count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
SavedList *savedList = [array objectAtIndex:indexPath.row];
cell.text = savedList.name;
}
return cell;
}
I hope it will be helpful.
// U need to reload table view data whenever you add new object in it. It does work like a thread.
dispatch_sync(dispatch_get_main_queue(), ^{
array = myJsonArray;
[self.tableView reloadData];

How to parse this json in uitableview? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I am new in iOS. I wanna parse following json in my UITableView, but I don't know how to do that. I know json parsing using NSURL, but in this direct json parsing I am facing problems .please help..
here it is:
NSString *url = #"{\"LinkResult\":{\"0\":{\"Name\":\"Veeva - Devon1\",\"ButtonDisplay\":\"Veeva\",\"PasswordSaving\":\"Yes\",\"Status\":\"Success\",\"Message\":\"No Error\", \"Identifiers\": {\"Identifier1Name\": \"Identifier1value\",\"Identifier2Name\": \"Identifier2value\",\"Identifier3Name\": \"Identifier3value\"},}}}";
please tell me next steps...
This is the structure of your JSON
{
"LinkResult": {
"0": {
"Name": "Veeva - Devon1",
"ButtonDisplay": "Veeva",
"PasswordSaving": "Yes",
"Status": "Success",
"Message": "No Error",
"Identifiers": {
"Identifier1Name": "Identifier1value",
"Identifier2Name": "Identifier2value",
"Identifier3Name": "Identifier3value"
}
}
}
}
Create a json file using any online generators and add it in your project. Have a property for keeping the dataSource.
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *filePath = [[NSBundle mainBundle]pathForResource:#"Data"
ofType:#"json"];
NSData *data = [[NSData alloc]initWithContentsOfFile:filePath];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data
options:0
error:nil];
//A dictionary which will contain info all users
self.users = dict[#"LinkResult"];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[self.users allKeys] count];;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NSArray *sortedKeys = [[self.users allKeys]sortedArrayUsingSelector:#selector(compare:)];
NSString *key = sortedKeys[indexPath.row];
NSDictionary *user = self.users[key];
cell.textLabel.text = user[#"Name"];
cell.detailTextLabel.text = user[#"Status"];
return cell;
}
Source Code
You'd want to use the NSJSONSerialization class for this, something like:
NSData *json = [url dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
NSDictionary *identifiers = [dataDictionary objectForKey:#"Identifiers"];
// Do stuff with the data
Hope that makes sense. You can pull elements from the JSON string by using:
[dataDictionary objectForKey:#"ElementName"];
to parse you could use nsdictionary like this...
NSData *json = [url dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
NSDictionary *identifiers = [dataDictionary objectForKey:#"Your key"];
and to show it in tableview you could use
arr = [[JSONObject objectForKey:#“results”] objectForKey:#“Your key”];
// and set cell text label as -
cell.textLabel.text =[[arr objectAtIndex:indexPath.row] objectForKey:#"Your key"];
You need to convert your json string to NSDictionary object in order to used in tableView,below code will convert it to NSDictionary object and then you can set values accordingly by using its key value.
- (void)viewDidLoad
{
NSString *jsonString = #"{\"LinkResult\":{\"0\":{\"Name\":\"Veeva - Devon1\",\"ButtonDisplay\":\"Veeva\",\"PasswordSaving\":\"Yes\",\"Status\":\"Success\",\"Message\":\"No Error\", \"Identifiers\": {\"Identifier1Name\": \"Identifier1value\",\"Identifier2Name\": \"Identifier2value\",\"Identifier3Name\": \"Identifier3value\"},}}}";
NSData *jsondata=[jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsondata options:0 error:nil];
displaydata=[[dataDictionary valueForKey:#"LinkResult"] valueForKey:#"0"];
NSMutableArray *mutableKeys=[[NSMutableArray alloc] initWithArray:[displaydata allKeys]];
[mutableKeys removeObject:#"Identifiers"];
keys=[[NSArray alloc] initWithArray:mutableKeys];
NSLog(#"JSON DIct: %#", displaydata);
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [keys count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier=#"cellIdentifier";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [displaydata valueForKey:[keys objectAtIndex:indexPath.row]];
return cell;
}
NSString *url = #"{\"LinkResult\":{\"0\":{\"Name\":\"Veeva - Devon1\",\"ButtonDisplay\":\"Veeva\",\"PasswordSaving\":\"Yes\",\"Status\":\"Success\",\"Message\":\"No Error\", \"Identifiers\": {\"Identifier1Name\": \"Identifier1value\",\"Identifier2Name\": \"Identifier2value\",\"Identifier3Name\": \"Identifier3value\"},}}}";
NSData* jsonData = [url dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
NSLog(#"json is %#", json);
NSDictionary *LinkResult = [json valueForKey:#"LinkResult"];
NSLog(#"LinkResult is %#", LinkResult);
for (id key in [LinkResult allKeys]) {
NSLog(#"Value for 0 index is %#", [LinkResult valueForKey:key]);
NSLog(#"ButtonDisplay is %#", [[LinkResult valueForKey:key] valueForKey:#"ButtonDisplay"]);
NSLog(#"Message is %#", [[LinkResult valueForKey:key] valueForKey:#"Message"]);
NSLog(#"Name is %#", [[LinkResult valueForKey:key] valueForKey:#"Name"]);
NSLog(#"PasswordSaving is %#", [[LinkResult valueForKey:key] valueForKey:#"PasswordSaving"]);
NSLog(#"Status is %#", [[LinkResult valueForKey:key] valueForKey:#"Status"]);
}
Here it is friend
NSString *url = #"{\"LinkResult\":{\"0\":{\"Name\":\"Veeva - Devon1\",\"ButtonDisplay\":\"Veeva\",\"PasswordSaving\":\"Yes\",\"Status\":\"Success\",\"Message\":\"No Error\", \"Identifiers\": {\"Identifier1Name\": \"Identifier1value\",\"Identifier2Name\": \"Identifier2value\",\"Identifier3Name\": \"Identifier3value\"},}}}";
NSArray *arrComponents = [url componentsSeparatedByString:#","];
NSMutableArray *arrmFilter = [[NSMutableArray alloc] init];
for(int i = 0; i < [arrComponents count] ;i++)
{
NSString *str = [arrComponents objectAtIndex:i];
//str = [str stringByReplacingOccurrencesOfString:#":" withString:#""];
str = [str stringByReplacingOccurrencesOfString:#"\"" withString:#""];
str = [str stringByReplacingOccurrencesOfString:#"{" withString:#""];
str = [str stringByReplacingOccurrencesOfString:#"}" withString:#""];
str = [str stringByReplacingOccurrencesOfString:#"0" withString:#""];
[arrmFilter addObject:str];
}
NSLog(#"Filtered array = %#", arrmFilter);
You Will have to do Some changes in `stringByReplacingOccurencesOfString
But this vill extract JSON....
Hope this helps..

displaying JSON data in Tableview in iphone

below is the JSON i want to parse it in such a way that for e.g date 1st should all events in that section of table and 2nd date should show all related events in another section
I am parsing using below code but i am not getting required sequence
SBJsonParser *parser= [[SBJsonParser alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.krsconnect.no/community/api.html?method=bareListEventsByCategory&appid=620&category-selected=350&counties-selected=Vest-Agder,Aust-Agder"]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSDictionary *object = [parser objectWithString:json_string error:nil];
NSArray *results = [parser objectWithString:json_string error:nil];
appDelegate.books1 = [[NSMutableArray alloc] init];
appDelegate.dates =[[NSMutableArray alloc]init];
for (int j=0;j<10; j++) {
NSDictionary *dictOne = [results objectAtIndex:j];
NSLog(#"%# - %#", [dictOne objectForKey:#"date"]);
Date *aDate = [[Date alloc] initWithDictionary:[results objectAtIndex:j]];
[appDelegate.dates addObject:aDate];
[aDate release];
}
for (int i=0; i<10; i++) {
NSDictionary *dictOne = [results objectAtIndex:i];
NSArray *activitiesArray = [dictOne objectForKey:#"events"];
NSDictionary *dictTwo = [activitiesArray objectAtIndex:i];
NSDictionary *eventDict=[dictTwo objectForKey:#"event"];
// NSLog(#"%# - %#", [dictOne objectForKey:#"date"]);
// NSLog(#"%# - %#", [dictTwo objectForKey:#"affectedDate"]);
// NSLog(#"%# - %#", [eventDict objectForKey:#"location"]);
NSInteger*date=[dictOne objectForKey:#"date"];
NSInteger*affectedDate=[dictTwo objectForKey:#"affectedDate"];
NSString*appId =[eventDict objectForKey:#"appId"];
NSString*eventId=[eventDict objectForKey:#"eventId"];
NSString*location=[eventDict objectForKey:#"location"];
NSString*municipality=[eventDict objectForKey:#"municipality"];
NSString*title=[eventDict objectForKey:#"title"];
Book1 *aBook=[[Book1 alloc] initWithDate:date affectedDate:affectedDate location:location municipality:municipality title:title];
[appDelegate.books1 addObject:aBook];
int count=[appDelegate.books1 count];
}
the json format is given below
http://www.krsconnect.no/community/api.html?method=bareListEventsByCategory&appid=620&category-selected=350&counties-selected=Vest-Agder,Aust-Agder
You need to aggregate your data in some different way.
Here is how I'd do that:
...
// why do you parse your json string two times?
//NSDictionary *object = [parser objectWithString:json_string error:nil];
NSArray *results = [parser objectWithString:json_string error:nil];
// You have memory leak here. I assume that books1 and dates are both properties with "retain" flag set.
//appDelegate.books1 = [[NSMutableArray alloc] init];
//appDelegate.dates =[[NSMutableArray alloc]init];
NSMutableArray *data = [NSMutableArray array]
self.data = data;
// check that what we've parsed is NSArray
if (results && [results isKindOfClass:[NSArray class]]) {
for (NSDictionary *sectionDict in results) {
if ([sectionDict isKindOfClass:[NSDictionary class]]) {
NSString *sectionTitle = [[sectionDict objectForKey:#"date"] description];
NSArray *events = [sectionDict objectForKey:#"events"];
if (date && events && [events isKindOfClass:[NSArray class]]) {
NSMutableArray *rows = [NSMutableArray arrayWithCapacity:[events count]];
for (NSDictionary *eventDict in events) {
if ([eventDict isKindOfClass:[NSDictionary class]]) {
[rows addObject:#"testRow"];
}
}
[data addObject:[NSDictionary dictionaryWithObjectsAndKeys: sectionTitle, #"section", rows, #"rows", nil]];
}
}
}
}
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tblView {
return [data count];
}
- (NSInteger) tableView:(UITableView *)tblView numberOfRowsInSection:(NSInteger)section {
return [[[data objectAtIndex:section] objectForKey:#"rows"] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[data objectAtIndex:section] objectForKey:#"section"];
}
- (UITableViewCell *) tableView:(UITableView *)tblView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"DefaultCell";
UITableViewCell *cell = (UITableViewCell *)[tblView dequeueReusableCellWithIdentifier:cellID];
if ( cell == nil ) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID] autorelease];
}
cell.textLabel.text = [[[data objectAtIndex:indexPath.section] objectForKey:#"rows"] objectAtIndex:indexPath.row];
return cell;
}

Cannot figure out why my app crashes when I use NSKeyedArchivers / NSKeyedUnarchivers

I am developing my first iphone 'Diary' app, which uses custom 'Entry' objects that hold an NSString title, NSString text and NSDate creationDate. When I try to archive an NSMutableArray of Entry objects, and later retrieve them the next time the view loads, the app crashes. I have gone through a bunch of sample codes and examples that use NSKeyedArchivers, but still couldn't figure out why that happens. I am guessing there is a problem with the initialization of the array that holds the entries but not sure...
Here is the code, maybe you could find something that I have persistently overseen..."
//--------- Entry.m---------------
- (id) initWithCoder:(NSCoder *)aDecoder{
if ((self = [super init])) {
self.title = [[aDecoder decodeObjectForKey:#"title"] retain];
self.text = [[aDecoder decodeObjectForKey:#"text"] retain];
self.created = [[aDecoder decodeObjectForKey:#"created"] retain];
}
return self;
}
- (void) encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.title forKey:#"title"];
[aCoder encodeObject:self.text forKey:#"text"];
[aCoder encodeObject:self.created forKey:#"created"];
}
//-------------- Diary View Controller.m
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFilename];
}
- (void) writeDataToArchive {
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
initForWritingWithMutableData:data];
[archiver encodeObject:self.entriesArray forKey:#"entriesArray"];
[archiver finishEncoding];
BOOL result = [data writeToFile:[self dataFilePath] atomically:YES];
[archiver release];
[data release];
}
- (void)addItem:sender {
int count = [entriesArray count] +1;
NSString *newEntryTitle = [NSString stringWithFormat:#"Entry %d", count];
Entry *anEntry = [[Entry alloc] initWithTitle:newEntryTitle text:#"-"
created:[NSDate date]];
[entriesArray addObject:anEntry];
[self.tableView reloadData];
[anEntry release];
[self writeDataToArchive];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSData *data = [[NSMutableData alloc]
initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
NSMutableArray *array = [unarchiver decodeObjectForKey:#"entriesArray"];
entriesArray = [array mutableCopy];
[array release];
[unarchiver finishDecoding];
[unarchiver release];
[data release];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
// ... some other stuff
NSUInteger row = indexPath.row;
Entry *entry = [entriesArray objectAtIndex:row];
cell.textLabel.text = entry.title;
return cell;
}
Thanks a lot.
When you read an array back out with NSKeyedUnarchivers you always get an unmutable copy back. You would need to declare *array as NSArray or just get rid of array all together.
entriesArray = [[unarchiver decodeObjectForKey:#"entriesArray"] mutableCopy];
And #JeremyP points out another issue. Since you didn't alloc or retain *array you should not release it.
You should not release array in viewDidLoad because you do not own it.
Please review the Cocoa memory management Rules because there are a couple of other memory management issues in your code. In particular,
self.title = [[aDecoder decodeObjectForKey:#"title"] retain];
self.text = [[aDecoder decodeObjectForKey:#"text"] retain];
self.created = [[aDecoder decodeObjectForKey:#"created"] retain];
in your initWithCoder: method all leak on the assumption the properties are retain or copy.

Json Parser output display in tableview

I am trying to parse using JSON Parser and the result which i get i have to put it into table view. I've passed a constant key value and a string .
Is there parsing steps wrong? or missed.
I have included the code for the JSON parser.
Thanks in advance.
SBJSON *parser = [[SBJSON alloc] init];
NSString *urlString =[NSString stringWithFormat:#"http://api.shopwiki.com/api/search?key=%#&q=%#",apiKey, string];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSMutableArray *statuses = [[NSMutableArray alloc]init];
statuses = [parser objectWithString:json_string error:nil];
NSLog(#"Array Contents: %#", statuses);
NSMutableArray *statuses0 = [[NSMutableArray alloc]init];
statuses0 = [statuses valueForKey:#"offers"];
NSLog(#"Array Contents: %#", statuses0);
//For Title
NSMutableArray *statuses1 = [[NSMutableArray alloc]init];
statuses1 = [[[statuses valueForKey:#"offers"] valueForKey:#"offer"]valueForKey:#"title"];
NSLog(#"Array Contents 4 Title: %#", statuses1);
Here in statuses1 array i get 20 objects which are all titles, now i just want to display that titles into tableview:-
snippet code for tableview:-
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"status count:%d",[statuses1 count]);
return [statuses1 count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Inside Tableview");
int counter=indexPath.row;
NSString *CellIdentifier = [NSString stringWithFormat:#"%d",counter];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
NSLog(#"Inside Tableview 1");
cell.textLabel.text=[statuses1 objectAtIndex:indexPath.row];
NSLog(#"Inside Tableview 2");
return cell;
}
I get Bad excess exception whten it hits on :-
cell.textLabel.text=[statuses1 objectAtIndex:indexPath.row];
Please give me the solution
thanks in advance:-
If you're getting EXC_BAD_ACCESS on that line, it's probably because statuses1 has been released by the time cellForRowAtIndexPath is called. What block of code is this line in?
NSMutableArray *statuses1 = [[NSMutableArray alloc]init];
The statuses1 variable above is local to whatever scope you've declared it in. Do you then assign it to your UITableViewController.statuses1 ivar? Is that a retained property?