Skip to content
David Richardson edited this page Dec 3, 2021 · 42 revisions

nib2cib is a command line tool designed for converting Cocoa’s nibs and xibs to Cappuccino’s cibs. It is still a work in progress but is now relatively far along, and is an excellent foundation for starting to fully support nib-style development on Cappuccino. A list of supported classes and features can be found below under “Support”

Building and Installing nib2cib

nib2cib is now included with normal distributions. Doing “rake install” from a Cappuccino checkout will automatically install the latest tools including nib2cib.

Using nib2cib

nib2cib converts nibs and xibs that you supply to it on the command line to Cappuccino’s cibs. Starting with version 0.7, you can choose the nib based application template with capp:

  1. $ capp gen -t NibApplication MyApp
  2. $ cd MyApp/Resources/
  3. Now edit the contained MainMenu.xib in Interface Builder
  4. $ nib2cib MainMenu.xib
  5. Test in browser

Note: currently this only works on Mac OS X since it uses ibtool.

Support

If `nib2cib` fails without producing a useful error message, confirm the source xib builds for ’macOS 10.10 and Later:

  • Open the xib in Interface Builder (Xcode)
  • Choose the ‘Identity and Type’ inspection panel
  • Use the Builds for control in the Interface Builder Document section

In Cappuccino 0.7.1 the following Cocoa classes and features are supported:

  • NSArray.j
  • NSButton.j
  • NSCell.j (NSCells, NSButtonCells, and NSActionCells)
  • NSClipView.j
  • NSColor.j
  • NSColorWell.j
  • NSControl.j
  • NSCustomObject.j
  • NSCustomResource.j
  • NSCustomView.j
  • NSFont.j
  • NSImageView.j
  • NSMatrix.j (currently only with radio buttons)
  • NSMenu.j
  • NSMenuItem.j
  • NSPopUpButton.j
  • NSResponder.j
  • NSScroller.j
  • NSScrollView.j
  • NSSet.j
  • NSSlider.j
  • NSSplitView.j
  • NSTabView.j
  • NSTabViewItem.j
  • NSTextField.j
  • NSView.j
  • NSViewController.j
  • NSWindowTemplate.j (Windows)
  • WebView.j

Additionally, these features work:

  • Target/Actions
  • Outlets

How It Works

The basic task behind nib2cib is to convert NS-classes to CP-classes. When you give it a nib or xib file, nib2cib opens the file, unarchives the actual NS-objects, converts them, and then archives the CP-equivalents. Although NS and CP are very similar, there are some difference between the two:

  1. File Format: nib2cib uses the 280N plist format which is optimized for the web. The normal plist format works as well, but is not as quickly unarchived online.
  2. Naming schemes: nib2cib must change all NS name references to CP name references.
  3. Coordinate spaces: Most NS classes put the origin of their coordinate spaces (0,0) at the bottom left, unless they are “flipped” (isFlipped returns YES). All CP classes behave like flipped NS classes. nib2cib must thus convert these properties.

So, for each NS-CP pair, we accomplish the conversion in the following way (we’ll use NSFont as an example):

1. Create a new decoding function in the CP class capable of decoding NS archives:


@implementation CPFont (NSCoding)

- (id)NS_initWithCoder:(CPCoder)aCoder
{
     return [self _initWithName:[aCoder decodeObjectForKey:@"NSName"]
                          size:[aCoder decodeDoubleForKey:@"NSSize"] bold:NO];
}

@end

As you can see here, we decode the NS keys and use them to construct a CP version of this object.

1. Create an NS-class in Objective-J that inherits from it’s CP analogue:


@implementation NSFont : CPFont
{
}
@end

2. Define it’s decoding method to just use the NS_ method we defined above:


- (id)initWithCoder:(CPCoder)aCoder
{
    return [self NS_initWithCoder:aCoder];
}

We’ve now successfully accomplished half the task: Unarchiving the NS archive. When NSFont is reached in a nib, it will call initWithCoder, which in turn will call NS_initWithCoder, creating an Objective-J NSFont.

3. Tell the archiver to use a replacement class. This last step is easy, all we do is tell the CPKeyedArchiver being used to create the cib file to archive ourselves as a CPFont, despite being an NSFont:


- (Class)classForKeyedArchiver { return [CPFont class]; }

Since the Objective-J version of NSFont inherits from CPFont, CPKeyedArchiver will have no trouble doing this (it will just use CPFont’s encodeWithCoder:).