0

I am having a table View with a list of category names loaded from the plist. i want to dynamically delete,add and reorder the list and save it to the plist.i used the code below and it is working great on simulator but its crashing on the device.

In ViewDid Load:
 self.categoryFile = [[NSBundle mainBundle]pathForResource:@"Categories" ofType:@"plist"];
 self.categoryList = [[NSMutableArray alloc]initWithContentsOfFile:self.categoryFile];

- (void)tableView:(UITableView *)tableView commitEditingStyle(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete){
    [[self categoryList] removeObjectAtIndex:[indexPath row]];
    NSArray *indexPathsToRemove = [NSArray arrayWithObject:indexPath];
    [tableView deleteRowsAtIndexPaths:indexPathsToRemove withRowAnimation:UITableViewRowAnimationRight];
    [tableView reloadData];
    NSArray *newArr = [[NSArray alloc]initWithArray:self.categoryList];
    [newArr writeToFile:self.categoryFile atomically:YES];
    [newArr release];
}

}

 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath{

NSString *contentsToMove = [[[self categoryList] objectAtIndex:[fromIndexPath row]] retain];
[[self categoryList] removeObjectAtIndex:[fromIndexPath row]];
[[self categoryList] insertObject:contentsToMove atIndex:[toIndexPath row]];
NSArray *newArr = [[NSArray alloc]initWithArray:self.categoryList];
[newArr writeToFile:self.categoryFile atomically:YES];
[newArr release];
[contentsToMove release];
}

The Error is coming at the line writeToFile: atomically.if i remove that line its working on device also but of no use.

Chandu
  • 695
  • 2
  • 12
  • 25

3 Answers3

0

You can't write to bundle resources on the device. Copy the plist to your app's documents directory when you first need it and read / update it from then on.

Code adapted from answer to this question:

- (NSString *)pathToPlist
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:@"Categories.plist"];
    BOOL copyProblem;
    if ([fileManager fileExistsAtPath:plistPath] == NO) {
        NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"Categories" ofType:@"plist"];
        copyProblem = [fileManager copyItemAtPath:resourcePath toPath:plistPath error:&error];
    }

    if (copyProblem)
        return nil;

    return plistPath
}

Assign this to self.categoryFile instead of the call out to NSBundle. Code was not compiled or tested so should be considered detailed psuedocode, please be prepared to correct small typos.

Community
  • 1
  • 1
Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
  • can u give me some code as i have no idea about what you are saying and that i am new to objective-C – Chandu Sep 28 '12 at 09:21
  • Every app has a read - only bundle and then a read-write sandbox which includes, among other things a documents directory. You copy files to the documents directory from the bundle if you want to write to them in your app. Code should be easy enough to dig up – Carl Veazey Sep 28 '12 at 09:25
  • @Chandu were you able to make any progress on this? Anything I can explain about the answer? – Carl Veazey Sep 30 '12 at 06:41
0

You have to first copy the file in the NSDocumentsDirectory(if it is not present there) if you want to edit and save the file later on. See this Link for reference

For loading your plist

BOOL success;
NSError *error;
NSString *filePath= [[NSBundle mainBundle] pathForResource:@"your_file" ofType:@"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString * path =[[NSString alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:@"your_file.plist"]];

success = [fileManager fileExistsAtPath:path];
if (success) {
    self.selectedObjectsDict=[[NSMutableDictionary alloc] initWithContentsOfFile:path];       

}
else
{    

    success = [fileManager copyItemAtPath:filePath  toPath:path error:&error];
    self.selectedObjectsDict=[[NSMutableDictionary alloc]initWithContentsOfFile:filePath];


}

For saving the plist

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString * path =[[NSString alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:@"your_file.plist"]];
[your_dict writeToFile:path atomically:YES];
Neo
  • 2,807
  • 1
  • 16
  • 18
0

What you are trying to do is delete a file from [NSBundle mainBundle] which can never happen as these file are read only..

If you want to delete and create files try it in DocumentsDirectory

Try this link for reference

Community
  • 1
  • 1
AppleDelegate
  • 4,269
  • 1
  • 20
  • 27