Search code examples
objective-ccocoadictionarynsbundlekey-value-store

How to store key-value data for cocoa apps within the app itself?


I have an info dictionary that contains user data. Currently, it is written to an xml file in the same directory as the app. However, I'm pretty certain cocoa allows me to write this xml file into the application bundle or some Resources directory within the app.

Can someone teach me how to do this?


Solution

  • You would want to use NSFileManager to createFileAtPath:contents:attributes: in the NSDocumentDirectory (relative to your bundle this is /Documents) with the NSData of your xml file.
    Something like this:

    NSString *myFileName = @"SOMEFILE.xml";
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    // This will give the absolute path of the Documents directory for your App
    NSString *docsDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    
    // This will join the Documents directory path and the file name to make a single absolute path (exactly like os.path.join, if you python)
    NSString *xmlWritePath = [docsDirPath stringByAppendingPathComponent:myFileName];
    
    // Replace this next line with something to turn your XML into an NSData
    NSData *xmlData = [[NSData alloc] initWithContentsOfURL:@"http://someurl.com/mydoc.xml"];
    
    // Write the file at xmlWritePath and put xmlData in the file.
    BOOL created = [fileManager createFileAtPath:xmlWritePath contents:xmlData attributes:nil];
    if (created) {
        NSLog(@"File created successfully!");
    } else {
        NSLog(@"File creation FAILED!");
    }
    
    // Only necessary if you are NOT using ARC and you alloc'd the NSData above:
    [xmlData release], xmlData = nil;
    

    Some references:

    NSFileManager Reference Docs
    NSData Reference Docs


    Edit

    In response to your comments, this would be typical usage of NSUserDefaults to save serializable data between App runs:

    // Some data that you would want to replace with your own XML / Dict / Array / etc
    NSMutableDictionary *nodeDict1 = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"object1", @"key1", nil];
    NSMutableDictionary *nodeDict2 = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"object2", @"key2", nil];
    NSArray *nodes = [NSArray arrayWithObjects:nodeDict1, nodeDict2, nil];
    
    // Save the object in standardUserDefaults
    [[NSUserDefaults standardUserDefaults] setObject:nodes forKey:@"XMLNODELIST"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    

    To retrieve a saved value (next time the App is launched, or from another part of the App, etc):

    NSArray *xmlNodeList = [[NSUserDefaults standardUserDefaults] arrayForKey:@"XMLNODELIST"];
    

    NSUserDefaults Reference Docs