user3283997
user3283997

Reputation:

Passing JSON objects from one table view to another table view

This is the structure of my JSON data

[
{
$id: "1",
Speeches: [],
Id: 1,
Year: "1999"
},
{
$id: "18",
Speeches: [],
Id: 2,
Year: "2000"
},
{
$id: "49",
Speeches: [],
Id: 3,
Year: "2001"
},

The structure of the speech object is as follows

Speeches: [
{
$id: "2",
Year: {
$ref: "1"
},
Id: 4,
YearId: 1,
Title: "الكلمة السامية بمناسبة زيارة قيادة الحرس الوطني تاريخ 30 مارس 1999",
HeaderOne: "بسم الله الرحمن الرحيم",
HeaderTwo: null,
Body: "أيها الأخوة والزملاء . . يسرني في هذا اليوم أن ألتقي بكم ، ولقد أردت بهذه الزيارة أن أرد لكم التحية على ما قمتم به .. وأظهرتموه في هذا الظرف الدقيق من تحاب وتكاتف كأسرة واحدة متراصة تسهر على سلامة الوطن وسلامة أهله والمقيميـن فيه في ظل دولة المؤسسات والقانون ..    وأن أشكر لكم مشاعركم تجاهنا في فقد والد الجميع أميرنا وقائدنا الراحل المغفور له سيدي صاحب السمو الشيخ عيسى بـن سلمان آل خليفة طيّب الله ثراه . . الذي كان بالفعل والد الجميع . . والذي جمعنا على الوئام والمحبة ، وعلى البذل والعطاء لهذا الوطن بلا حدود . . وفي ظل هذه المسيرة ، وتحت هذه الراية ومن هذا الموقع يطيب لي أن أوجه باسمكم جميعاً ، التقدير والتحية إلى الوالد العم العزيز صاحب
ImageName: "img787.png"
},
{
$id: "3",
Year: {
$ref: "1"
},
Id: 5,
YearId: 1,
Title: "الكلمة السامية الأولى بعد تولي مقاليد الحكم في البلاد تاريخ 13 مارس 1999م",
HeaderOne: "بسم الله الرحمن الرحيم",
HeaderTwo: null,
Body: "شعبنـا العزيـز …  السلام عليكم ورحمة الله وبركاته ،  قال تعالى : " من المؤمنين رجالٌ صدقوا ما عاهدوا الله عليه ، فمنهم من قضى نحبه ، ومنهم من ينتظر ، وما بدلوا تبديلا " صدق الله العظيم .   أما بعد :-  ففي هذا الموقف التاريخي يجمعنا واياكم المصاب الجلل في فقيدنا العظيم ووالدنا القائد ،    وتوحّدنا واياكم ، في الوقت ذاته ، مسؤولية التطلع بثـقة للمستقبل لمواصلة المسيرة على النهج الذي رسمه لنا من واسع حكمته وإخلاصه وسماحته ، هذا مع الاستعداد لمواجهة 
ImageName: "img002.png"
},

I need to display the years in one table view followed by the title of the speeches in the respective year in a second table view. I've modeled two data objects Year and Speech as follows:

@interface Year : NSObject

@property (nonatomic, strong) NSString *yearName;
@property (nonatomic, strong) NSArray *speeches;

@end

and

@interface Speech : NSObject

@property (nonatomic, strong) NSString *title;
@property(nonatomic,strong) NSString *header;
@property(nonatomic,strong) NSString *body;
@property(nonatomic,strong) NSString *image;

@end

Retrieving the data and displaying the works fine. This is how I'm doing it.

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSURL *dataApi = [NSURL URLWithString:@"http://vbahrain.azurewebsites.net/api/yearapi"];

    NSData *jsonData =[NSData dataWithContentsOfURL:dataApi];

//    NSLog(@"%@", jsonData);

    NSError *error = nil;



    self.years = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];

    self.yearBucket = [NSMutableArray array];


    for (NSDictionary * dict in self.years) {

        Year *year = [[Year alloc ]init];

        year.yearName =[dict objectForKey:@"Year"];
        year.speeches = [dict objectForKey:@"Speeches"];

        [self.yearBucket addObject:year];
    }

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    Year *year = [self.yearBucket objectAtIndex:indexPath.row];


    cell.textLabel.text = year.yearName;


    cell.detailTextLabel.text = [NSString stringWithFormat:@"%lu", [year.speeches count]];

    return cell;
}

Now I'm trying to pass the data to the next View controller using the prepare for segue method as described below

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].

    TitleViewController *tvc = [segue destinationViewController];

    // Pass the selected object to the new view controller.

    NSIndexPath *path = [self.tableView indexPathForSelectedRow];

    Year *selectedYear = self.yearBucket[path.row];


    for (NSDictionary *dict in selectedYear.speeches){


        Speech *speech = [[Speech alloc ]init];

        speech.title =[dict objectForKey:@"Title"];
        speech.header = [dict objectForKey:@"HeaderOne"];
        speech.body = [dict objectForKey:@"Body"];

      [tvc.speechesForSelectedYear addObject:speech];
}

Now this is the method I'm using to display this data passed in the speechesForSelectedYear Mutable array. Here's first the header of the other table view

@interface TitleViewController : UITableViewController

@property (nonatomic, strong) NSMutableArray *speechesForSelectedYear;

@end


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...

    Speech *speech = [self.speechesForSelectedYear objectAtIndex:indexPath.row];

    cell.textLabel.text = speech.title;


    return cell;
}

However the second table view is displaying nothing. Where am I going wrong?

Upvotes: 0

Views: 403

Answers (1)

drolando
drolando

Reputation: 507

Try to add in the class of your second table:

@synthesize speechesForSelectedYear=_speechesForSelectedYear;

-(NSMutableArray*)speechesForSelectedYear
{
    if (!_speechesForSelectedYear)
        _speechesForSelectedYear = [[ NSMutableArray alloc] init];
    return _speechesForSelectedYear;
}

The problem may be that the speechesForSelectedYear array is not allocated when you call [tvc.speechesForSelectedYear addObject:speech]. With this function you override the getter of the property so you're sure that wherever you use it the array exists.

In Objective-c if the array is nil you will not get an error or an exception but nothing'll happen.

Upvotes: 1

Related Questions