24
May
2008
 

Cocoa Tutorial: Working With Application Resources

by Matt Long

For most simple applications using and managing resources is handled seamlessly and you don’t ever have to intervene programatically. There are times, however, as your applications begin to mature that you need to access resources directly. Doing so is pretty straightforward, but I thought I would document it here–if for no other reason than to have it written down somewhere for the next time I need it. I hope it might be helpful to you too.

It’s Automagical

Any files that you add to your Resources directory in your xcode project are automatically added to your application build. You can verify this with the following steps:

  1. Build your application in xcode

  2. Navigate to your project build directory and locate the .app file that was created while building–usually in either <project_path>/build/Debug or <project_path>/build/Release.

  3. Once you’ve found the application file, Ctrl-click the file and select Show Package Contents

  4. In the ensuing Finder window drill down into Contents:Resources

  5. You will see all of your resources files for your project there.

Now the question becomes, what’s the simplest way to get access to these resources in code. Fortunately, Cocoa makes it easy.

Loading A Property List Template

I recently needed to keep a property list file handy to use as a template for saving data. As you probably know, an NSDictionary provides a way to save the dictionary data as a property list. In this case, I didn’t see any reason why I would need to build up a dictionary from scratch in code when I could instead load in a template property list and just make changes to the parts of the ensuing dictionary that needed changed. The obvious solution to me for keeping a hold of this property list file was to just store it within the resources directory inside of my application. I then just need to grab the file from the application’s main bundle and I am in business. Here is the code I used to load in the property list file.

1
2
3
4
NSString *path = [[NSBundle mainBundle] pathForResource:@"OutputTemplate" ofType:@"plist"];
 
NSMutableDictionary *templateDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:path];
NSLog(@"Dictionary was: %@", templateDictionary);
Note: The actual file name of the file we’re loading from the main bundle is OutputTemplate.plist

Now I can simply maniupate the NSMutableDictionary, giving it the keys and values it needs. Then, later, I simply write the dictionary out to a specified output file as follows.

1
[templateDictionary writeToFile:outputPath atomically:YES];

Conclusion

You can use this technique to load any file type you like. Just add your file that you want to your Resources directory and you’ll be good to go. To be sure, this is simply what seemed to be the best way to handle this problem to me. If you are aware of some other method that is considered a best practice, let me know. I’m always looking for a better way to do things.

Per bbum’s suggestion, this is now filed under radar: 5972712

Matt Long

Matt Long works for Colorado Springs iOS Development shop, Skye Road Systems. He is the founder and principal developer there. Matt also works for a startup company called Galen Medical Systems where he develops apps for the medical industry. Contact Matt at Matt at CIMGF dot com to discuss your iOS software development needs. Matt is the co-founder of Cocoa Is My Girlfriend and is the co-author of "Core Animation: Simplified Animation Techniques for Mac and iPhone Development"

More Posts - Website

Follow Me:
Twitter

Comments

Ross says:

Let’s say you’ve got some global constants that you want to define in a plist rather than in code. (The constants might contain non-ASCII characters, for example.) Where would you put the code that reads the plist and sets the constants? I’m guessing that the +initialize method of the app delegate is the best place. What’s your advice?

Matt Long says:

-applicationDidFinishLaunching or -awakeFromNib is where I would suggest.

Matt

shivaprasad2452 says:

i have doing document based application .. i have to load a window called template window inital after user select one template i have to load document window…. i done this my loading template window in applicationWillFinishLaunching after saving when user double click on app it must load document window…. but it loading template window how to avoid that….. please sugesst…