tags:

views:

787

answers:

3

Hey everyone. I am working on an app that displays a modal the first time the consumer uses it. I have a .plist file that will store the information I request once the Save button is pressed. I can read from the .plist file fine and when I run my save method it SEEMS to work fine but the .plist file is not updating. I'm not so sure of the problem here. I show the modal like this.

 - (void) getConsumerInfo {
 NSString *filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"consumer.plist"];
 NSMutableDictionary *plistConsumerInfo = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];

 NSString *hasAppeared = [plistConsumerInfo objectForKey:@"HasAppeared"];

 if(hasAppeared != kHasAppeared) {
  ConsumerInfoViewController *tmpConsumerInfoVC = [[ConsumerInfoViewController alloc]
               initWithNibName:@"ConsumerInfoView" bundle:nil];
  self.consumerInfoViewController = tmpConsumerInfoVC;
  [self presentModalViewController:consumerInfoViewController animated:YES];
  [tmpConsumerInfoVC release];
 }
}

This is called by the viewDidLoad method in the first view phone when the app is started. Within the consumerInfoViewController I have textfields that have data entered and when the Save button is pressed it calls this method.

    - (IBAction)saveConsumerInfo:(id)sender {
 NSString *filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"consumer.plist"];
 NSMutableDictionary *plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];

 NSString *tmpDiversName = txtDiversName.text;
 NSString *tmpLicenseType = txtLicenseType.text;
 NSString *tmpLicenseNum = txtLicenseNumber.text;
 NSString *tmpHasAppeared = @"1";
 NSString *tmpNumJumps = @"3";

 [plistDict setValue:[[NSString alloc] initWithFormat:@"%@", tmpDiversName] forKey:@"ConsumerName"];
 [plistDict setValue:[[NSString alloc] initWithFormat:@"%@", tmpLicenseType] forKey:@"LicenseType"];
 [plistDict setValue:[[NSString alloc] initWithFormat:@"%@", tmpLicenseNum] forKey:@"LicenseNumb"];
 [plistDict setValue:[[NSString alloc] initWithFormat:@"%@", tmpNumJumps] forKey:@"NumJumps"];
 [plistDict setValue:[[NSString alloc] initWithFormat:@"%d", tmpHasAppeared] forKey:@"Show"];
 [plistDict writeToFile:filePath atomically: YES];
 NSLog([[NSString alloc] initWithContentsOfFile:filePath]);
 [self dismissModalViewControllerAnimated:YES];
}

This all runs fine with no hiccups but the file is never updated. I would like it to update so I can use this information throughout the app and update the flag so it will not show the view again once the data is entered. Please let me know if there is anymore information you need. Thanks in advance!

+2  A: 

You cannot write to the bundle directory.

Use the Caches folder or the Documents folder instead. See the iPhone docs for info on how to modify the returns of the NSSearchPathForDirectoriesInDomains or NSHomeDirectory functions to find the locations of these folders - somewhere to place data.

martinr
Awesome! Thats it but I guess I am having another issue. I can go and look at the plist file on the file system and the values are there but it seems to have created 2 more value key pairs. Weird. I want it to use the plist file that I imported into the resource folder. I guess I will have to figure that one out too. Thanks for the answer!
Trent
If it was me, I'd use the absence of the plist file in the Caches or Documents folder as a FLAG that the app has never *successfully fully started* before, and only create the plist file in Caches/Documents after the app and/or the user *successfully and fully* complete the initial "first app run" workflow.
martinr
A: 

Just to add to this, you CAN write to the bundle in the simulator, even if you can't on the device - something that caused me to wast a heap of time debugging between the simulator and the device

AJ
A: 

If this is of any use to anyone, this is some code I use to do something similar. I use it to copy some sample documents the first run, or optionally (the commented section) copy when a new version is greater than the last version if it is warranted.

BOOL firstrun()
{
    CFStringRef firstRunKey = CFSTR("lastVersion");

    CFNumberFormatterRef formatter;

    CFStringRef currentVersionString;
    CFMutableStringRef currentVersionMutableString;
    CFNumberRef currentVersion;

    CFStringRef lastVersionRunString;
//  CFMutableStringRef lastVersionRunMutableString;
//  CFNumberRef lastVersionRun;



    currentVersionString = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey);
    currentVersionMutableString = CFStringCreateMutableCopy(NULL, 0, currentVersionString);
    CFStringFindAndReplace(currentVersionMutableString, CFSTR("."), CFSTR(""), CFRangeMake(0, CFStringGetLength(currentVersionString)), 0);
    formatter = CFNumberFormatterCreate(NULL, NULL, kCFNumberFormatterNoStyle);
    currentVersion = CFNumberFormatterCreateNumberFromString(NULL, formatter, currentVersionMutableString, NULL, kCFNumberFormatterParseIntegersOnly);

    lastVersionRunString = CFPreferencesCopyAppValue(firstRunKey, kCFPreferencesCurrentApplication);

    if (lastVersionRunString == NULL)
    {
        // first run
        NSFileManager *f = [NSFileManager defaultManager];
        NSBundle *b = [NSBundle mainBundle];
        NSError *e;

        NSArray *xs = [NSArray arrayWithObjects: @"Welcome", 
                              @"A Child's Garden of Verses", 
                                     @"Address to a Haggis", 
                                               @"Sonnet 18", nil];

        for (id x in xs)
        {
            BOOL s = [f copyItemAtPath: [b pathForResource: x ofType: @"txt"] 
                   toPath: [DocumentManager pathForDocumentWithName: x]  
                    error: &e];

            if (s == YES)
            {
                NSLog(@"Copied first run file %@ successfully.", x);
            }
            else {
                NSLog(@"Failed to copy %@.", x);
            }
        }
    } // else {
        // The following is to enable support for new releases needing to show new information
/*
        lastVersionRunMutableString = CFStringCreateMutableCopy(NULL, 0, lastVersionRunString);
        CFStringFindAndReplace(lastVersionRunMutableString, 
                               CFSTR("."), 
                               CFSTR(""), 
                               CFRangeMake(0, CFStringGetLength(lastVersionRunMutableString)), 
                               0);
        lastVersionRun = CFNumberFormatterCreateNumberFromString(NULL, formatter, lastVersionRunMutableString, NULL, kCFNumberFormatterParseIntegersOnly);

        CFComparisonResult cr = CFNumberCompare(lastVersionRun, currentVersion, NULL);
*/      

//  }

    // Update last run version
    CFPreferencesSetAppValue(firstRunKey, currentVersionString, kCFPreferencesCurrentApplication);
    CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);

    CFRelease(currentVersionMutableString);
    CFRelease(formatter);
    CFRelease(currentVersion);

    return (lastVersionRunString == NULL);

    }
iaefai