Daddy
Daddy

Reputation: 9035

Including files inside the iPhone Bundle Library Path

I'm having trouble with my update logic. I need to include a file in the app bundle which contains specific update data. When the app discovers this file, it checks to see if it's a first install (no update needed) or a previous install (apply update). Whatever the outcome, the update file needs to be deleted, so it's not found again, otherwise the app will apply the update each time the app is run, which is bad.

Since it's impossible to remove anything from [[NSBundle mainBundle], I need to figure out the best way to do this. If I could include the update file inside of the Application's Library path, it would be much simpler.

The reason I need this is because on first load, the application creates a file of user data and stores it inside the Library path. From then on, the application loads that user file. In this case, the file that was created has outdated data. I created a new file with updated data to apply to the user's main file.

Can anyone help me through this? here's what i have:

if ([self checkUpdateFile] == YES) {
    [self applyUpdate];
}

-(BOOL)checkUpdateFile {
NSString *updateFilePath = [[NSBundle mainBundle]pathForResource:@"updateData"
        ofType:@"dat" inDirectory:@"update"];
BOOL updateFileExists = [[NSFileManager defaultManager]
        fileExistsAtPath: updateFilePath];
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
        NSUserDomainMask, YES) objectAtIndex:0];
NSString *programDataPath = [libraryPath stringByAppendingPathComponent: 
        @"programData.dat"];
BOOL programFileExists = [[NSFileManager defaultManager]fileExistsAtPath: 
        programDataPath];
if (programFileExists == YES && updateFileExists == YES) {
    NSLog(@"Update File is present, and so is a data file, so this is a previous install");
    return YES;
} else {
    NSLog(@"This is not an upgradeable version.");
    if (updateFileExists == YES) {
        NSLog(@"The update file is here but this is the first install.");
        [[NSFileManager defaultManager]removeItemAtPath: updateFilePath 
                        error:NULL];
        BOOL doesFileStillExist = [[NSFileManager defaultManager] 
                        fileExistsAtPath:updateFilePath];
        if (doesFileStillExist == YES) {
            NSLog(@"File still exists");
        } else {
            NSLog(@"File was deleted.");
        }
    }
    return NO;
}
}

-(void)applyUpdate {
NSLog(@"Applying Update");
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"updateData" 
        ofType:@"dat" inDirectory:@"update"];
NSData *programData = [[NSData alloc] initWithContentsOfFile:filePath];
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] 
        initForReadingWithData:programData];
NSMutableArray *characterList = [[decoder 
        decodeObjectForKey:@"characterList"]retain];
int i = 0;
for (Character *player in characterList) {
    NSMutableArray *movesList = player.moves;
    Character *existingCharacter = [self.dataController.characterList 
                objectAtIndex:i];
    NSLog(@"Found Character: %@",existingCharacter.name);
    existingCharacter.moves = movesList;
    i++;
}

BOOL doesFileStillExist = [[NSFileManager defaultManager] 
         fileExistsAtPath:filePath];
if (doesFileStillExist == YES) {
    NSLog(@"File still exists");
} else {
    NSLog(@"File was deleted.");
}
[self writeDataToDisk];
[characterList release];
[decoder release];
[programData release];

}

Upvotes: 1

Views: 1190

Answers (3)

Scott Johnson
Scott Johnson

Reputation: 11

I have discovered that when adding files to the main bundle it sometimes will not find them in the main bundle in your code. The file will appear in the file pane, but it is not recognized, or found, using this code:

NSString *file = [[NSBundle mainBundle] pathForResource:@"fileName" ofType:@"db"];

Select the file in question and delete it's reference only, then using the menu item: and add the file back to the project. This seems to trigger some internal flag in Xcode that causes the compiler to re-compile it into the project.

Upvotes: 1

TomH
TomH

Reputation: 2990

If app is running on first launch, make your update. As the update data is part of your main bundle, you will not be able to delete the file

After you have made the update, write a BOOL entry to a plist file (something like appIsUpdated).

On subsequent launches, check for existence of the plist file and the value of appIsUpdated. If !appIsUpdated, update the app.

Upvotes: 1

Shaggy Frog
Shaggy Frog

Reputation: 27601

You answered your own question; you can't delete files inside the application bundle. Treat the whole bundle like a read-only directory.

You'll have to clarify exactly why you're trying to do this as I don't understand it from your description. Try explaining it at a high level (a "functional" description) -- what do you want to happen and why? (Not how you want something to happen, which is a low-level or "non-functional" description.)

Upvotes: 0

Related Questions