Peter
Peter

Reputation: 31

MonoTouch <--> Static Library Exception : Could not load NIB in bundle

I've a static library, developed with Xcode 4, this library contains an own UIViewController.
Now I am trying to use this View and its controller from my MonoTouch project.
But at the moment when the view is trying to load the NIB file, I get the following exception:

"NSInternalInconsistencyException Reason: Could not load NIB in bundle".

Is there a way to use a exisiting UIViewController from a Objective-C static library within a MonoTouch project?

Upvotes: 3

Views: 1026

Answers (1)

Brian Nickel
Brian Nickel

Reputation: 27560

This isn't really a MonoTouch-specific problem, this is happening because the nib file doesn't exist in the main bundle. NIB files (and images for that matter) are not packaged in libraries but are instead packaged in resource bundles. If you "Show Package Contents" on your .app you will see all your files fromt the main app either in the root directory or en.lproj. You will not see nib files for your library because your app didn't know to build it.

The quickest fix is to move your .xib file to your MonoTouch main project and it should instantly work, though this is unsatisfying. An alternative, and I've only done this in XCode, is to add an bundle target to your library project to hold your resources.

Steps to create the bundle:

  1. In your library project, add a new target using OS X -> Framework & Library -> Bundle. Don't worry about the "OS X" part. Name it something like "MyLibrary".
  2. You should see "MyLibraryResources.bundle" appear in the build product.
  3. In this new target, add the .xib file to the "Copy Bundle Resources" build phase.
  4. Add the "MyLibraryResources.bundle" build product to the "Copy Bundle Resources" build phase of your app.

Now if you build you app, it will still crash, but if you look inside your .app file you will see the directory "MyLibraryResources.bundle" with your NIB file. The next step is to make your view controller reference that NIB.

Find where you're calling initWithNib:bundle:. It's time to set the bundle! The following step creates a bundle:

NSBundle *myLibraryBundle = [NSBundle bundleWithURL:[[NSBundle mainBundle]
    URLForResource:@"MyLibraryResources" withExtension:@"bundle"]];

If you pass initWithNib:@"MyViewController" bundle:myLibraryBundle it should work. You will probably want to package myLibraryBundle up in a way where you only call it once per app execution.

Upvotes: 4

Related Questions