Developer's Blog

Nib ファイルから Objective-C のソースコードを生成する

iOS/Mac 開発担当の松本です。

突然ですが、Nib ファイル(以下 Nib)が好きになれません。確かに GUI の部品をレイアウトするコードを書くのは大変なので、Interface Builder で直感的に画面を作っていけるのはありがたいです。

しかし Visual Studio 等と違って、作った画面がソースコードではなく Nib というリソースになるため、言語や環境によって動的に部品を変更する必要が出てくると、Nib とソースコードに画面を作成する為の情報が散らばってしまいますね。これだと管理コストも高くなりますし、何より気持ちが悪いです。

どうしてソースコードが生成されないんだ!と憤っていたら、nib2objc という Nib から Objective-C のコードを生成するツールが、公開されていることを知りました。しかも随分前からあるみたいです。

早速ですが Mosa の、この Nib を使って実験してみました。

Action Panel of Mosa

使い方は簡単で変換したい Nib ファイルを指定するだけです。標準出力に変換後のソースコードが出力されるので必要ならリダイレクトしましょう。

$ nib2objc ActionPanel.xib

生成されたソースコードが以下になります。コメントを少し追加しました。そのままこのコードを使うのは難しいかなというのが正直な感想です。ただ Nib で作った部品のプロパティにどのような値が設定されているのか等の勉強にはなるので、初めて使うコントロール等を一度ダンプしてみる価値はあるかもしれません。

// 背景パネル
UIImageView *imageview91 = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 416.0)];
imageview91.alpha = 0.700;
imageview91.autoresizesSubviews = YES;
imageview91.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
imageview91.clearsContextBeforeDrawing = NO;
imageview91.clipsToBounds = NO;
imageview91.contentMode = UIViewContentModeCenter;
imageview91.contentStretch = CGRectFromString(@"{{0, 0}, {1, 1}}");
imageview91.frame = CGRectMake(0.0, 0.0, 320.0, 416.0);
imageview91.hidden = NO;
imageview91.highlighted = NO;
imageview91.image = nil;
imageview91.multipleTouchEnabled = NO;
imageview91.opaque = NO;
imageview91.tag = 0;
imageview91.userInteractionEnabled = NO;

// AA表示ボタン
UIButton *button152 = [UIButton buttonWithType:UIButtonTypeCustom];
button152.adjustsImageWhenDisabled = YES;
button152.adjustsImageWhenHighlighted = YES;
button152.alpha = 1.000;
button152.autoresizesSubviews = YES;
button152.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
button152.clearsContextBeforeDrawing = YES;
button152.clipsToBounds = NO;
button152.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
button152.contentMode = UIViewContentModeScaleToFill;
button152.contentStretch = CGRectFromString(@"{{0, 0}, {1, 1}}");
button152.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
button152.enabled = YES;
button152.frame = CGRectMake(12.0, 10.0, 90.0, 74.0);
button152.hidden = NO;
button152.highlighted = NO;
button152.multipleTouchEnabled = NO;
button152.opaque = NO;
button152.reversesTitleShadowWhenHighlighted = NO;
button152.selected = NO;
button152.showsTouchWhenHighlighted = NO;
button152.tag = 0;
button152.titleLabel.lineBreakMode = UILineBreakModeMiddleTruncation;
button152.titleLabel.shadowOffset = CGSizeMake(0.0, 0.0);
button152.userInteractionEnabled = YES;
[button152 setTitleColor:[UIColor colorWithRed:0.196 green:0.310 blue:0.522 alpha:1.000] forState:UIControlStateNormal];
[button152 setTitleColor:[UIColor colorWithWhite:1.000 alpha:1.000] forState:UIControlStateHighlighted];
[button152 setTitleShadowColor:[UIColor colorWithWhite:0.500 alpha:1.000] forState:UIControlStateNormal];

// 長いので以下省略
// ...

ちなみにどうやってコード生成してるのかなと思って、nib2objc 自体のソースを見てみると ibtool を使って Nib からパーツの親子関係等の必要な情報を抜き出して、それぞれの部品に対応したコンバータクラスが書かれていました。凄い力技です。

nib2objc 面白いんですけど、実際のプロジェクトで使うとなるとビルドの仕組み等も含めてもう一歩という所ですね。

Nib を使って言語もプラットフォームも吸収するいい方法、どなたかご存知でしたら教えてください。

Copyright © 2019 Fenrir Inc. All rights reserved.