David van Dugteren
David van Dugteren

Reputation: 4109

PList Chicken/Egg Scenario

I want to read/write to cache.plist

If I want to read an existing premade plist file stored in the resources folder I can go:

path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathWithComponent@"cache.plist"];
NSMutableDictionary *root = ...

But then I wish to read it from the iPhone.

Can't, the Resources folder is only readable.

So I need to use:

NSDocumentDirectory, NSUserDomain,YES

So how can I have my plist file preinstalled to the Document Directory location?

Thus meaning I don't have to mess around with untidy code copying the plist file over at startup. (Unless that's the only way).

Upvotes: 0

Views: 365

Answers (3)

David van Dugteren
David van Dugteren

Reputation: 4109

The final product

NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:@"Cache.plist"];


NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *giveCachePath = [documentsDirectory stringByAppendingPathComponent:@"Cache.plist"];


BOOL fileExists = [fileManager fileExistsAtPath:giveCachePath];

if (fileExists) {
    NSLog(@"file Exists");
}
else {
    NSLog(@"Copying the file over");
    fileExists = [fileManager copyItemAtPath:finalPath toPath:giveCachePath error:&error];
}

NSLog(@"Confirming Copy:");

BOOL filecopied = [fileManager fileExistsAtPath:giveCachePath];

if (filecopied) {
    NSLog(@"Give Cache Plist File ready.");
}
else {
    NSLog(@"Cache plist not working.");
}

Upvotes: 1

Dave DeLong
Dave DeLong

Reputation: 243156

Easy. Look first to see if it's in the documents directory. If it's not, find it inside your app's Resources folder ([[NSBundle mainBundle] pathForResource...]), then copy it into the documents directory using [[NSFileManager defaultManager] copyItemAtPath:...]. Then use the fresh copy in the documents directory with impunity.

Upvotes: 1

Ben Williams
Ben Williams

Reputation: 4695

I know this isn't really what you're after, but as far as I know the only way to get the document into the Documents folder IS to actually copy it there...but only on the first startup. I'm going something similar for a sqlite database. Code is below, it works but please note it could do with a little bit of cleaning up:

// Creates a writable copy of the bundled default database in the application Documents directory.
- (void)createEditableCopyOfDatabaseIfNeeded {
    // First, test for existence.
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"WordsDatabase.sqlite3"];
    createdDatabaseOk = [fileManager fileExistsAtPath:writableDBPath];
    if (createdDatabaseOk) return;
    // The writable database does not exist, so copy the default to the appropriate location.
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"WordsDatabase.sqlite3"];
    createdDatabaseOk = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
}

Just call in your AppDelegate - not too messy really?

Upvotes: 1

Related Questions