12

I have a bunch of directories and files in my app, for instance images/misc/mainmenu_background.. I'm running the following code in the "iPad Simulator 3.2":

NSString *images = [[NSBundle mainBundle] pathForResource:@"images" ofType:nil];
NSString *images_misc = [[NSBundle mainBundle] pathForResource:@"images/misc" ofType:nil];
NSString *images_misc_file = [[NSBundle mainBundle] pathForResource:@"images/misc/mainmenu_background.png" ofType:nil];

After this call, images contains the path /Users/wic/Library/Application Support/iPhone Simulator/3.2/Applications/8F67150B-71E6-4735-8CC6-38B3CE6D3568/Foo.app/images.

But images_misc and images_misc_file are nil. Double-checking my file system to check if the file is there:

$ ls -l "/Users/wic/Library/Application Support/iPhone Simulator/3.2/Applications/8F67150B-71E6-4735-8CC6-38B3CE6D3568/Foo.app/images/misc/mainmenu_background.png"
-rw-rw-rw-  1 wic  staff  30307 16 Feb 21:09 /Users/wic/Library/Application Support/iPhone Simulator/3.2/Applications/8F67150B-71E6-4735-8CC6-38B3CE6D3568/Foo.app/images/misc/mainmenu_background.png

Apparently the file is there.

If I switch to "iPad Simulator 4.0", or any other simulator version for that matter everything works as expected.

Is there something wrong with my setup, or is this correct behavior for NSBundle in iPad 3.2? I have no actual physical iPad to test it on unfortunately.

Martin Wickman
  • 19,662
  • 12
  • 82
  • 106

2 Answers2

23

If you need to access a file in a directory, you should be using -[NSBundle pathForResource:ofType:inDirectory:] instead. So your code should instead look like

NSString *images_misc_file = [[NSBundle mainBundle] pathForResource:@"mainmenu_background" ofType:@"png" inDirectory:@"images/misc"];
Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • Ok, thanks. Using `inDirectory` seems to work. But this means the behavior has (silently) changed as it works in later versions, right? – Martin Wickman Feb 16 '11 at 22:58
  • It sounds like they changed the method to handle full paths given in the `pathForResource:` parameter, but even if you're only supporting 4.0 and above it's better to use the API correctly and use the `inDirectory:` parameter for all directories. – Lily Ballard Feb 17 '11 at 00:57
  • For the record, it's a framework I'm using which does it like that. Odd that apple changed this behavior w/o any notice though. – Martin Wickman Feb 17 '11 at 16:41
  • They made it more permissive. Probably as a side-effect of reimplementing the method for some other change (e.g. supporting @2x or ~ipad modifiers). – Lily Ballard Feb 17 '11 at 21:46
10

Even though this has been answered already, I would like to add that -[NSBundle pathForResource:ofType:inDirectory:] has different case-sensitivity depending whether it is iPhone simulator or iPad simulator or the device. For example, iPhone Simulator 4.0 it seems to be case insensitive, while on iPad Simulator 3.2 and the device - case sensitive. Thus files that are found on iPhone 4.0 simulator might not be found on IPad Simulator 3.2 or the device if the cases don't match.

mt_
  • 335
  • 2
  • 13