Question

I've written an app which list the title, a thumbnail and the second-hand price of some books. It's all done using a UITableView and the data is taken from a .plist file.

What I want to add is a checkbox to each cell which can be toggled if the user has the book or not and then store that checkbox state for the next time they use the app. Is it possible to store a value back to the .plist file or is there another way to do it?

Here's the code I have so far for the cell:

@implementation ffbooksCell

@synthesize ffbooksLabel = _ffbooksLabel;
@synthesize priceLabel = _priceLabel;
@synthesize thumbnailImageView = _thumbnailImageView;


- (void) viewDidLoad {
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    NSString* path = [documentsDirectory stringByAppendingPathComponent:@"ffbooks.plist"];
    NSMutableArray* checkboxSelected = nil;
    // Attempt to load saved data from the documents directory
    if ([[NSFileManager defaultManager] fileExistsAtPath:path]){
        checkboxSelected = [NSMutableArray arrayWithContentsOfFile:path];
    }else{
        // No saved data in documents directory so we need to load the data from the bundle
        NSString* bundlePath = [[NSBundle mainBundle] pathForResource:@"ffbooks" ofType:@"plist"];
        checkboxSelected = [NSMutableArray arrayWithContentsOfFile:bundlePath];
    }

    //...
    // Toggle check box for book 0
    if ([checkboxSelected[0][@"checkbox"] boolValue]){
        checkboxSelected[0][@"checkbox"] = @NO;
    }else{
        checkboxSelected[0][@"checkbox"] = @YES;
    }
    // Note: @"checkbox" does not need to be in the original plist
    //...

    [checkboxSelected writeToFile:path atomically:YES];

    if (checkboxSelected == 0){
        [checkboxButton setSelected:NO];
    } else {
        [checkboxButton setSelected:YES];
    }

}

- (IBAction)checkboxButton:(id)sender{

    if (checkboxSelected == 0){
        [checkboxButton setSelected:YES];
        checkboxSelected = 1;
    } else {
        [checkboxButton setSelected:NO];
        checkboxSelected = 0;
    }

}


- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}


@end
Was it helpful?

Solution

There are lots of alternatives to storing the data in a plist. Core Data would be my choice. Learning how to use core data is worth the time investment. You could still use the plist to pre populate your database.

However to answer your question yes you can store the data in a plist. Assuming the initial data is stored in the bundle and is an array of dictionaries here is some example code.

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

NSString* path = [documentsDirectory stringByAppendingPathComponent:@"books.plist"];
NSMutableArray* info = nil;
// Attempt to load saved data from the documents directory
if ([[NSFileManager defaultManager] fileExistsAtPath:path]){
    info = [NSMutableArray arrayWithContentsOfFile:path];
}else{
    // No saved data in documents directory so we need to load the data from the bundle
    NSString* bundlePath = [[NSBundle mainBundle] pathForResource:@"books" ofType:@"plist"];
    info = [NSMutableArray arrayWithContentsOfFile:bundlePath];
}

//...
// Toggle check box for book 0
if ([info[0][@"checkbox"] boolValue]){
    info[0][@"checkbox"] = @NO;
}else{
    info[0][@"checkbox"] = @YES;
}
// Note: @"checkbox" does not need to be in the original plist
[info writeToFile:path atomically:YES];

Update: I have created a gist for you to help you load the data into a table view controller https://gist.github.com/datinc/9075686

OTHER TIPS

You can use NSUserDefaultsto store small amount of data (mostly like settings...)

Just check this tutorial

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