Diggory
Diggory

Reputation: 645

Why is my bundle ignoring its info.plist?

I am attempting to bundle a set of resources into a bundle, and them access them from code via NSBundle.

So far, I can access the resources from the bundle fine, but I cannot get the NSBundle instance to get any meta-data from the bundle's Info.plist file.

Strangely, my first attempt worked, and correctly got the meta-data, but since then I have been unable to replicate this behaviour and the bundle always returns null for the bundleIdentifier or other items in the infoDictionary.

I have reduced the code to the following test case:

NSString *pathToTestBundle = [[NSBundle mainBundle] pathForResource:@"test" 
                                                    ofType:@"testBundle"];
NSLog(@"path to Test Bundle: %@", pathToTestBundle);

NSBundle *testBundle = [NSBundle bundleWithPath: pathToTestBundle];
NSLog(@"testBundle: %@", testBundle);

NSString *identifier = [testBundle bundleIdentifier];
NSLog(@"testBundle identifier: %@", identifier);

NSURL *testResourceURL = [testBundle URLForResource:@"vanGroup" 
                                       withExtension:@"png"];
NSLog(@"testBundle test resource: %@", testResourceURL);

NSImage *testImage = [[NSImage alloc] initByReferencingURL:testResourceURL]; 
[imageView setImage:testImage];

NSLog(@"%@", [testBundle infoDictionary]);

Which gives this: (edited for line length)

path to Test Bundle: /.../BundleTester.app/Contents/Resources/test.testBundle
testBundle: NSBundle </../BundleTester.app/Contents/Resources/test.testBundle> 
      (not yet loaded)
testBundle identifier: (null)
testBundle test resource: file://.../BundleTester.app/Contents/Resources/test.testBundle/Resources/vanGroup.png
BundleTester[45083:707] {
    NSBundleInitialPath = "/Users/diggory/Library/Developer/Xcode/DerivedData/BundleTester-hcbsnhudsdfzlyggjbvlkdbrtxrw/Build/Products/Debug/BundleTester.app/Contents/Resources/test.testBundle";
    NSBundleResolvedPath = "/Users/diggory/Library/Developer/Xcode/DerivedData/BundleTester-hcbsnhudsdfzlyggjbvlkdbrtxrw/Build/Products/Debug/BundleTester.app/Contents/Resources/test.testBundle";
}

In my Xcode project by test bundle is added as a folder reference and has the following structure:

test.testBundle
    Info.plist
    Resources
        vanGroup.png

The image resource is loaded correctly, but the values in the plist are ignored.

The plist is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleIdentifier</key>
    <string>com.monkeyfood.testbundle</string>
    <key>badger</key>
    <string>Bodger</string>
</dict>
</plist>

Am I missing something? What am I doing wrong?
Many thanks.

Upvotes: 0

Views: 984

Answers (2)

lbrndnr
lbrndnr

Reputation: 3389

The "Contents" folder is missing.

Upvotes: 1

Suhail Patel
Suhail Patel

Reputation: 13694

It seems your bundle object is referring to the Bundle but the Bundle isn't yet loaded which is why you get null when you call bundleIdentifier. From Apple's Documentation on Bundle Loading Code

To load a bundle’s executable code, use NSBundle’s load method. This method returns YES if loading was successful or if the code had already been loaded, and NO otherwise.

You need to call [bundle load] like so:

NSBundle *testBundle = [NSBundle bundleWithPath: pathToTestBundle];
[testBundle load];   // Load the bundle...

More information on Bundle Loading is explained in Apple's Documentation

Upvotes: 1

Related Questions