Mario
Mario

Reputation: 65

Objective-c load and write plist - error

Hi I'm practicing with plists and I learned that there are 2 different ways to load them

FIRST METHOD:

NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documents = [path lastObject];
NSString *filePath = [documents stringByAppendingPathComponent:@"test.plist"]; 
self.array = [NSArray arrayWithContentsOfFile:filePath];

SECOND METHOD:

NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Ingredients" ofType:@"plist"];
self.array = [NSArray arrayWithContentsOfFile:filePath];

I don't understand clearly which way it's best... but I noticed that if I use the second one, I can't write in the plist. can anyone tell me more about it? which is the best and correct way? What's the difference?

i'm doing some tests and i have some code working only with one method...

//using this code the nslog will print null

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0];
    NSString *filePath = [documentsPath stringByAppendingPathComponent:@"Ingredients.plist"];
    ingredients = [NSMutableArray arrayWithContentsOfFile:filePath];
    NSLog(@"ingredients:%@", self.ingredients);



//using this code the nslog will print the content of the array

    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Ingredients" ofType:@"plist"];
    ingredients = [NSMutableArray arrayWithContentsOfFile:filePath];

    NSLog(@"Authors:%@", self.ingredients);

Upvotes: 0

Views: 227

Answers (1)

icodebuster
icodebuster

Reputation: 8974

First Method

Your app only (on a non-jailbroken device) runs in a "sandboxed" environment. This means that it can only access files and directories within its own contents. For example Documents and Library.

Reference iOS Application Programming Guide.

To access the Documents directory of your applications sandbox, you can use the following:

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

This Documents directory allows you to store files and subdirectories your app creates or may need.

To access files in the Library directory of your apps sandbox use (in place of pathsabove):

[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]

Second Method

The Second Method is used to write the file in the Apps main bundle.

The main bundle is the bundle that contains the code and resources for the running application. If you are an application developer, this is the most commonly used bundle. The main bundle is also the easiest to retrieve because it does not require you to provide any information.

It is better to copy the file from App Main Bundle to App Document Directory and then use the document directories path to read/write file.

If you are using the first method you need to copy the file from your main resources to the Documents Directory.

Code to Copy file from app bundle to App's Document Directory

#define FILE_NAME @"sample.plist"

// Function to create a writable copy of the bundled file in the application Documents directory.

- (void)createCopyOfFileIfNeeded {

    // First, test for existence.
    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:FILE_NAME];

    success = [fileManager fileExistsAtPath:filePath];
    if (success){
        return;
    }
    // The writable file does not exist, so copy the default to the appropriate location.
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:FILE_NAME];
    success = [fileManager copyItemAtPath:defaultDBPath toPath:filePath error:&error];
    if (!success) {
        NSAssert1(0, @"Failed to create writable file with message '%@'.", [error localizedDescription]);
    }
}

Sample Code Dropbox Link

Upvotes: 1

Related Questions