Question

I'm newbie in Objective-C, I'm learning it. Now I'm trying to solve the problem to save and load my array from plist after app's restart. Thanks a lot for the answers. Now I have the following code, that still doesn't work.

First of all I get the path to plist:

//get the path to plist-file
- (NSString *)getPathToPlist
{
    @try
    {
        DDLogVerbose(@"getPathToPlist method has been started...");

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);   //create a list of paths
        //NSString *documentsDirectory = [paths objectAtIndex:0];                                             //get a path to your documents directory from the list
        NSString *documentsDirectory = [paths firstObject];                                             //get a path to your documents directory from the list
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"BGMToDoItems.plist"];               //create a full file path

        DDLogVerbose(@"getPathToPlist method has been completed. Your path is: %@", path);

        return path;
    }
    @catch(NSException *exception) //catch the exception
    {
        DDLogError(@"Error! Something is wrong in getPathToPlist method. Catching %@ reason %@", [exception name], [exception reason]);
    }

}

After this I have two methods. One for save my array to plist:

//save array to plist
- (void)plistSave
{
    DDLogVerbose(@"plistSave method has been started...");

    //get the path to plist-file
    NSString *path = [self getPathToPlist];
    [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
    //save toDoItems to file
    @try
    {

        [self.toDoItems writeToFile:path atomically: YES];
    }
    @catch (NSException *exception)
    {
        DDLogError(@"Error! Something is wrong while toDoItems array was saving (plistSave method). Catching %@ reason %@", [exception name], [exception reason]);
    }

    DDLogVerbose(@"Your plist successfully saved."); 
}

And the other one for load:

//initialization of the toDoItems array (load from plist or initial creation)
- (void) plistArrayLoad: (NSString *)path
{
    DDLogVerbose(@"plistArrayLoad method has been started with path param %@...", path);

    //check the plist existing
    NSFileManager *fileManager = [NSFileManager defaultManager];

    if (![fileManager fileExistsAtPath:path]) //if plist doesn't exist
    {
        DDLogVerbose(@"Your plist file doesn't exist, so I'll create one...");

        //create the plist file in your documents directory from the bundle directory (by XCode)
        @try
        {
            NSError *error;

            NSString *bundle = [[NSBundle mainBundle] pathForResource:@"BGMToDoItems" ofType:@"plist"]; //get the path to your plist created before in bundle directory (by XCode)
            [fileManager copyItemAtPath:bundle toPath:path error:&error];                                //copy plist to your documents directory
            DDLogVerbose(@"Plist file successfully created.");

            //load the default array as ToDoItems to memory
            self.toDoItems = [[NSMutableArray alloc] init]; //memory allocation
            [self defaultArrayFill];                        //fill in the array with default items
        }
        @catch (NSException *exception)
        {
            DDLogError(@"Error! Something is wrong while plist init (plistArrayLoad method). Catching %@ reason %@", [exception name], [exception reason]);
        }
    }
    else //if user's plist exist
    {
        @try
        {
            DDLogVerbose(@"Your plist file exist. Your toDoItems array is loading from %@...", path);

            //self.toDoItems = [[NSMutableArray alloc] init]; //memory allocation
            self.toDoItems = [NSMutableArray arrayWithContentsOfFile:path];

            DDLogVerbose(@"Your toDoItems array successfully loaded.");
        }
        @catch (NSException *exception)
        {
            DDLogError(@"Error! Something is wrong while toDoItems array was loading (plistArrayLoad method). Catching %@ reason %@", [exception name], [exception reason]);
        }
    }

}

When I have the first run my "IF" works like "plist doesn't exist" and everything is OK, I see the "defaultArrayFill" in my UITableView. I can edit it. But at the second run, when my "IF" works like plist exist. I see a clear table without any data... All logs are correct I see start and end of each method which have to work.

What am I doing wrong?

Help me please. I apologize but I'm learning it my first code topic on stackoverflow

Thanks a lot for the answers.

Was it helpful?

Solution

There might be mistake in your method where you create the path. If you log the path then you will find that it is not what you expect. Use stringByAppendingPathComponent: to add the filename to create the full path.

 - (NSString *)getPathToPlist
{
    @try
    {
         DDLogVerbose(@"getPathToPlist method has been started...");

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);   //create a list of paths
        NSString *documentsDirectory = [paths firstObject];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"BGMToDoItems.plist"];               //create a full file path

       DDLogVerbose(@"getPathToPlist method has been completed. Your path is: %@", path);

       return path;
    }
    @catch(NSException *exception) //catch the exception
    {
        DDLogError(@"Error! Something is wrong in getPathToPlist method. Catching %@ reason %@", [exception name], [exception reason]);

    }
}

- (void) plistArrayLoad: (NSString *)path
{
    DDLogVerbose(@"Your plist file exist. Your toDoItems array is loading from %@...", path);

   self.toDoItems = [NSMutableArray arrayWithContentsOfFile:path];

   DDLogVerbose(@"Your toDoItems array successfully loaded.");   
}

- (void)plistSave
{
     DDLogVerbose(@"plistSave method has been started...");
    NSString *path = [self getPathToPlist];
    NSLog(@"path %@", path);
    [self.toDoItems writeToFile:path atomically: YES];
    DDLogVerbose(@"Your plist successfully saved."); 

}

OTHER TIPS

When generating your path try using

NSString *path = [documentsDirectory stringByAppendingPathComponent:@"BGMToDoItems.plist"];

instead of

NSString *path = [documentsDirectory stringByAppendingString:@"BGMToDoItems.plist"];

this will automatically add a slash between the components. The way you are doing it now the app would try to create the file DocumentsBGMToDoItems.plist in the parent directory to wich you don´t have write permissions.

Also you probably should use

[[NSFileManager defaultManager] removeItemAtPath:path error:nil];

to delete the file before you save the new one as writeToFile: does not overwrite existing files.

About the exceptions: Objective-C isn't Java. You throw exceptions for programming errors. You don't catch them, you fix the code. Your trying to catch exceptions only means your program may run into trouble and mess things up.

For example, getPathToPlist won't even return a result if it catches an exception.

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