NSBundle, plist and other resources in an Obj-c Static Library
Asked Answered
S

3

20

I've created a static library in Xcode, which I am able to successfully use in other projects. However, with resources like plists, I find I must include any plists referenced in my library in the main project where the project is used.

In my static library project, I have my plist included in the "Copy Bundle Resources" phase of the target. In my code, here is what I am doing:

NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath   = [mainBundle pathForResource:@"MyClassParams" ofType:@"plist"];

NSMutableDictionary* params = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];

If I use mainBundle and the MyClassParams.plist is included in the main project, all is good. If MyClassParams.plist is included in the library project, it doesn't work.

On the assumption that [NSBundle mainBundle] was referencing the wrong static method to use, I replaced it with:

NSBundle *mainBundle = [NSBundle bundleForClass:[MyClass class]];

This did not work either.

So, is it possible to include a plist or any other resources with a static library -- or do I have to include whatever I need in the project where the lib is used?

Saiva answered 1/11, 2009 at 16:35 Comment(1)
Starting a bounty with the question -- is the accepted answer still correct as of iOS 4.2?Lawtun
S
19

Static Libraries are not in bundles, when they get linked into an application they are part of that applications bundle. On the iPhone, effectively all code you write will be in the mainBundle since you can't include embedded frameworks.

So yes, you need to copy over all the resources into the project you are linking the static framework into.

Samons answered 2/11, 2009 at 2:6 Comment(0)
G
13

I know you can't include resource files into a static library (that's what frameworks do). I use another solution in my projects:

Inside the static library "YYY" project:

  • I add a "Loadable Bundle" target to my static library project (Add Target, Cocoa, Loadable Bundle)
  • I add this target as a dependency of the static library target

Inside the main project:

  • Link the libYYY.a
  • Add the bundle YYY.bundle to the copied resource files

This way, resource files used in the static library are not managed in the main project. Say I have a foo.png picture in the static library, I use

[UIImage imageNamed:@"YYY.bundle/foo.png"]

You could then get your plist like this:

NSBundle *staticLibBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"YYY" ofType:@"bundle"]];
NSString *filePath   = [staticLibBundle pathForResource:@"MyClassParams" ofType:@"plist"];

NSMutableDictionary *params = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];

Below, two screenshots:

  • left: static library project with loadable bundle target
  • right: showing the static library binary added to "Link Binary With Libraries" and the resource bundle added to "Copy bundle Resources".

Static library project Main project

Gongorism answered 27/12, 2010 at 14:37 Comment(6)
hi jilouc . .i am stuck up with the last step . .what is copied resource files ? . plz explainPiliferous
@Piliferous Just drag-and-drop the bundle file to you Resources (as you would do for any other resource file) and add it to your project target. I've added a screenshot.Gongorism
jil . . i have a doubt . .i added test.bundle from /projectname/staticprojectfolder/build/Release-iphonesimulator . .is that correct ? what happens when i build my app on mobile ? will it work properly of where should the actual reference be done . .Piliferous
@Piliferous Since it only contains images or other resources, you can use any generated bundle. (But if you want, you can build your static library for "Device" and use the bundle from /projectname/staticprojectfolder/build/Release-iphoneos)Gongorism
With the "Copy Bundle Resources" step, after browsing to the built location make sure you add it via 'folder reference' for it to work.Disjoint
Good answer. If you get stuck, I found there's a more detailed writeup of this, with many screenshots, here: galloway.me.uk/tutorials/ios-library-with-resourcesWestnorthwest
Q
2

I followed everything @Jilouc suggested, however, I can get the bundle but failed to get files inside it. I tried both the two ways (@"yyy.bundle/image" or staticlib pathforresource...)

Then I used the method below and it worked!

NSBundle *staticBundle = [NSBundle bundleWithPath:[[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:@"yy.bundle"]];

NSString *filePath = [[jsBundle resourcePath]stringByAppendingPathComponent:fileName];

NSString* content = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
Quince answered 23/7, 2011 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.