views:

334

answers:

2

Hey all,

I'm looking into a project that would upload custom NSBundles that include a NSViewController. In my main program I've got this code to deal with the bundle after it's been loaded...

id principalClass = [loadedBundle principalClass];
id instance = [[principalClass alloc] init];
[localLabel setStringValue:[instance name]];
NSView *incomingView = [[instance viewController] view];
[localView addSubview:incomingView];
[localView display];

And the principal classes init method in the bundle looks like this...

-(id) init {
    if(self = [super init]){
        name = @"My Plugin";
        viewController = [[ViewController alloc] initWithNibName:@"View" bundle:nil];
    }
    return self;
}

View.nib is a nib located in the bundles project. But whenever I load the bundle I get this error...

2010-05-27 09:11:18.423 PluginLoader[45032:a0f] unable to find nib named: View in bundle path: (null) 2010-05-27 09:11:18.424 PluginLoader[45032:a0f] -[NSViewController loadView] could not load the "View" nib.

I know I've got everything wired up because the line [label setStringValue:[instance name]]; sets the label text correctly. Plus, if I take all of the clases in the bundle and load them into my main applications project everything works as expect. Any thoughts on how I can correctly reference "View" in my bundle?

Thanks!

A: 

"View.xib is a nib"? Either it is a xib or it is a nib. A xib is not a nib. xib files can only be used in the interface builder, in deployment applications they must be transformed to nib files. That is what ibtool is doing. Xcode does not simply copy your xib files, it runs them through ibtool that converts them to nib files that are then placed into the Resources folder.

Mecki
A xib is a nib, just in XML format. Interface builder can work with xibs or nibs, but xibs are more convenient for development because they work better with SCM tools.
dreamlax
@dreamlax: Apple's documentation is very clear about the fact, that xib files are not intended to be deployed. Even when creating a debug build you are supposed to transform xib into nib files during copy phase. Apple does not guarantee anywhere that every method/function that can handle nib files can equally handle xib files. Consider xib files like PDFs (vector graphics, text and bitmaps) and nib files like PNG files (bitmap only). Not every image function that can handle PNG images can handle PDF documents.
Mecki
You are confusing the nib/xib *file format* with the nib file. See [this doc](http://developer.apple.com/iphone/library/documentation/DeveloperTools/Conceptual/IB_UserGuide/BuildingaNibFile/BuildingaNibFile.html#//apple_ref/doc/uid/TP40005344-CH11-SW14). The xib file format still represents a nib file. A nib file has two formats, xib, and nib. Before xib was introduced (for the sole purpose of better SCM support), a nib file had one format, the nib file format. From the link: "The xib file format represents a flattened archive of the nib file object graph."
dreamlax
@dreamlax: Following your link, which part of the following sentences found there is unclear to you: "Files of this type have a .xib extension and can be used only within the Xcode and Interface Builder environments. You cannot load .xib files at runtime from your application code."? "You cannot load" pretty much back-ups everything I have said before.
Mecki
@Mecki: Read the whole document: "Interface Builder documents are files with the extension .nib or .xib. These documents are often referred to as *nib files*." The extension represents the underlying representation of a nib file [object graph].
dreamlax
I don't doubt that you can't load xib files at runtime, but a .xib file is a nib file.
dreamlax
But a nib file is loadable at runtime, a xib file is not. They might both describe the same thing, but they are not the same kind of file, otherwise they both would be loadable at runtime. And if someone says he cannot load a file at runtime and at the same time talks about a xib file, then I must assume this user really means a xib file and this file **cannot be loaded** at runtime.
Mecki
+2  A: 

In the init method, you shouldn't pass nil to the bundle parameter. According to the UIViewController documentation, passing nil will look up the NIB file in the main bundle (the application's one), which is not what you want.

You can workaround, by using a specialized initializer like this:

- (id) initWithBundle:(NSBundle *)bundle {
    if(self = [super init]){
        name = @"My Plugin";
        viewController = [[ViewController alloc] initWithNibName:@"View" bundle:bundle];
    }
    return self;
}

And use it as follow:

Class principalClass = [loadedBundle principalClass];
id instance = [[principalClass alloc] initWithBundle:loadedBundle];
Laurent Etiemble
`[loadedBundle principalClass]` returns type `Class`, not `id`. For readability reasons I would probably use `Class` type for the `principalClass` variable.
dreamlax
Right on the head. And within 20 minutes! Thanks man
Staros