Question

I have an NSArray of songs fetched from a server. That is my raw data source. The array contains custom objects which have an NSDictionary and NSArray as backend.

I am wondering if implementing a formatted data source using an NSDictionary will be wise. The dictionary will have section headers as keys, and the value of a certain key will have an NSArray containing the rows for that section.

I will be iterating through my raw data source and arranging it alphabetically into the dictionary.

I have a feeling that this is not a solid implementation and is very expensive. Is there any other, more solid implementation than this?

Was it helpful?

Solution

For small tables, rather than NSDictionary, I generally use NSArray, since dictionaries don't preserve order (and you probably don't want to continually re-sort). So I usually have an array of sections, for which I have for each section entry, at the very least, a section title and an array of rows. My array of rows has, that information that I need to present a given row (e.g. the text of the row, etc.).

The individual row and section objects, you can implement those as a NSDictionary objects themselves (and sometimes when parsing the data from JSON or XML, that's easiest), but I generally define my own Row and Section objects, e.g.:

@interface Row : NSObject

@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *subtitle;

@end

and

@interface Section : NSObject

@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSMutableArray *rows;

@end

Then my table view controller has an NSArray for the sections:

@property (nonatomic, strong) NSMutableArray *sections;

And I populate it like so:

self.sections = [NSMutableArray array];

Section *sectionObject;

sectionObject = [[Section alloc] initWithTitle:@"Marx Brothers" rows:nil];
[sectionObject.rows addObject:[[Row alloc] initWithTitle:@"Chico"   subtitle:@"Leonard Marx"]];
[sectionObject.rows addObject:[[Row alloc] initWithTitle:@"Harpo"   subtitle:@"Adolph Marx"]];
[sectionObject.rows addObject:[[Row alloc] initWithTitle:@"Groucho" subtitle:@"Julius Henry Marx"]];
[sectionObject.rows addObject:[[Row alloc] initWithTitle:@"Zeppo"   subtitle:@"Herbert Manfred Marx"]];
[self.sections addObject:sectionObject];

sectionObject = [[Section alloc] initWithTitle:@"Three Stooges" rows:nil];
[sectionObject.rows addObject:[[Row alloc] initWithTitle:@"Moe"   subtitle:@"Moses Harry Horwitz"]];
[sectionObject.rows addObject:[[Row alloc] initWithTitle:@"Larry" subtitle:@"Louis Feinberg"]];
[sectionObject.rows addObject:[[Row alloc] initWithTitle:@"Curly" subtitle:@"Jerome Lester \"Jerry\" Horwitz"]];
[self.sections addObject:sectionObject];

And then I have the typical UITableViewDataSource methods:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [self.sections count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    Section *sectionObject = self.sections[section];
    return [sectionObject.rows count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    Section *sectionObject = self.sections[section];
    return sectionObject.title;
}

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

    Section *sectionObject = self.sections[indexPath.section];
    Row *rowObject = sectionObject.rows[indexPath.row];

    cell.textLabel.text = rowObject.title;
    cell.detailTextLabel.text = rowObject.subtitle;

    return cell;
}

For bigger, database data driven tables, I might not keep the data in arrays, but rather use Core Data or SQLite, but the idea is the same. Make sure I have Section and Row classes that keep my table view controller code self-explanatory and insulated from the details of the data implementation.

OTHER TIPS

Have you tried RestKit? All you need is to provide source of json encoded objects and create model classes

You can use a model class and then create objects of this model class with the data from the server. Then use the array of model class objects as a source to your UITableView.
You could also consider core-data , in which its very easy to create data models and relations. However it comes with a lot of additional features which might be extra baggage for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top