iOS SDKによるiPhone/iPadアプリケーション開発入門

第2回iOSアプリケーションの基本構成

連載2回目となる今回は、いわゆるHello Worldプロジェクトの作成します。ただしInterface Builderを使った一般的な方法とは異なり、コードのみでプログラムを作成します。それを通してiOSアプリケーションの構成要素の基礎を理解することを目指します。

プロジェクトの作成

Xcodeで新規プロジェクトを作成します。プロジェクト名は「GihyoSample01」とします。テンプレートにWindow-based Applicationを選択します。Productは"iPhone"とし、"Use Core Data for storage"にはチェックを付けないようにします。

図1 プロジェクトの作成
図1 プロジェクトの作成

nibファイルを使わないアプリケーションの設定

プロジェクトの作成が完了したら、まずはアプリケーションのロードをnibファイルから行わないように変更します。nibファイルから起動するための設定はGiphyoSample01-Info.plistファイルに記述されています。コードでアプリケーションを起動するためにはこの設定を削除する必要があります。ついでにMainWindow.xib自体も削除してしまいましょう(下図参照⁠⁠。

図2 nibファイルの削除
図2 nibファイルの削除

続いて、Other Sourcesにあるmain.mを見てみます。ここにあるmain関数からアプリケーションが起動されます。

int main(int argc, char *argv[]) {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  // --- (1)
  int retVal = UIApplicationMain(argc, argv, nil, @"GihyoSample01AppDelegate");  // --- (2)
  [pool release];
  return retVal;
}

main関数内では以下のことが行われています。

まず、自動開放プールが初期化されています(main.m-(1)⁠⁠。これはプログラム内でautoreleaseを利用できるようにするためのものです。

次に、UIApplicationMainはアプリケーションの初期化を行う関数で、4つの引数を受け取っています(main.m-(2)⁠⁠。

argc, argvは、起動時にアプリケーションから渡されたすべての引数が含まれます。

第3パラメータにはアプリケーションの主クラス名を指定します。nilを指定するとUIApplicationクラスが使用されます。これは通常変更する必要はありません。

第4パラメータにはアプリケーションデリゲートのクラス名を指定します。nilを指定するとnibファイル(通常MainWindow.nib)からアプリケーションデリゲートをロードするという意味になります。Interface Builderを使わずにコードでアプリケーションを作成するには、ここにアプリケーションデリゲートのクラス名を渡す必要があります。

ここでは、UIApplicationMain関数の第4引数にGihyoSample01AppDelegateという文字列を指定することで、アプリケーションデリゲートクラスにGihyoSample01AppDelegateを使用することを指示しています。

iOSアプリケーションの構成

アプリケーションデリゲートクラス

アプリケーションデリゲートクラスは、アプリケーションの起動が完了した場合や、バックグラウンドに移動された際、リモート、ローカル通知を受け取った時、アプリケーションが修了された際など、アプリケーションイベントに対する動作をカスタマイズするために実装するクラスです。コード的にはUIApplicationDelegateプロトコルを実装したクラスをとなります。最低限の仕事としてはアプリケーションの起動が完了した際に呼び出されるapplication:didFinishLaunchingWithOptions:メソッドを実装することです。

ウィンドウ、ビュー、ビューコントローラ

ウィンドウは、iOSアプリケーションの画面全体を表現します。通常UIWindowクラスのオブジェクトを使用します。一方ビューはナビゲーションバー、ボタン、テキストボックスなどの、画面上に表示される一つのコンポーネントを表現するオブジェクトです。これらはUIViewまたはそのサブクラスのオブジェクトとして実装されています。ビューはウィンドウに貼りつけられる形で画面に表示されます。

ビューコントローラは一連のビューの表示と管理を担当するオブジェクトで、UIViewControllerクラスのサブクラスとして実装されます。これは端末の向きを変えたときの動きに代表される、iOSアプリケーションで使われる標準的なインタフェース動作のデフォルト実装を提供してくれます。

実際のコード

アプリケーションデリゲートクラスのコード

アプリケーションデリゲートクラスのヘッダファイルは以下のとおりです。

GihyoSample01AppDelegate.h
#import <UIKit/UIKit.h>

@class RootViewController;  // -- (1)

@interface GihyoSample01AppDelegate : NSObject <UIApplicationDelegate> {
  UIWindow *window;  // -- (2)
  RootViewController *viewController;  // -- (3)
}

@property (nonatomic, retain) UIWindow *window;
@property (nonatomic, retain) RootViewController *viewController;  // --(4)

@end

(1)でこの後作成するビューコントローラを前方宣言しておきます。

(2)はウィンドウオブジェクトへのポインタを保持する変数です。

(3)はアプリケーションの実行起点となるビューコントローラへのポインタを保持する変数です。

(4)でビューコントローラをプロパティとして宣言しています。

続いて、アプリケーションデリゲートクラスの実装部分になります。

GihyoSample01AppDelegate.m
#import "GihyoSample01AppDelegate.h"
#import "RootViewController.h" // --- (1)

@implementation GihyoSample01AppDelegate

@synthesize window;
@synthesize viewController; // --- (2)

#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  // --- (3)
  window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];  // --- (4)
  viewController = [[RootViewController alloc]init];   // --- (5)

  [window addSubview:viewController.view];   // --- (6)
  [window makeKeyAndVisible];  // --- (7)

  return YES;
}

- (void)dealloc {
  [viewController release];  // ---(8)
  [window release];
  [super dealloc];
}

@end

(1) あとで定義するビューコントローラクラスの定義を読み込んでいます。

(2) プロパティ宣言に対する実装です。

(3) アプリケーションの起動が完了した際に呼び出されるメソッドです。UIApplicationDelegateプロトロルで定義されています。

(4) [[UIScreen mainScreen]bounds]によって、ステータスバーを含む画面全体の領域が取得できます。現状のiPhoneですと通常(0,0,480,320)というCGRect構造体が取得できます。このサイズ(つまりはiPhoneの画面全体)をもとにウィンドウオブジェクトを作成しています。

(5) ビューコントローラオブジェクトを生成しています。

(6) ビューコントローラが管理するビューを上で作成したウィンドウオブジェクトのサブビューとして貼り付けます。

(7) 最後にmakeKeyAndVisibleメソッドを使ってウィンドウを最前面に移動して表示しています。

(8) 確保したビューコントローラオブジェクトをリリースします。

ビューコントローラクラスのコード

ビューコントローラのヘッダファイルは以下のとおりです。

RootViewController.h
#import 

@interface RootViewController : UIViewController {
  UITextView *textView; // -- (1)
}

@end

(1) 今回表示するテキストビューを保持するポインタを宣言しています。

続いて、ビューコントローラの実装部分になります。

RootViewController.m
#import "RootViewController.h"

@implementation RootViewController

- (void)loadView {  // -- (1)
  textView = [[UITextView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]]; // --- (2)
  textView.text = @"Hello World";  // --- (3)
  textView.textAlignment = UITextAlignmentCenter;  // --- (4)
  self.view = textView;  // -- (5)
}

- (void)dealloc {
  [textView release];  // -- (6)
  [super dealloc];
}

@end

(1) ビューをnibファイルからロードする際には通常このメソッドはオーバーロードしません。このメソッドをオーバーライドした際には、ここで必要なビューを作成して、viewプロパティに適切なビューオブジェクトを設定する必要があります。

(2) UIScreenオブジェクトのapplicationFrameメソッドにより、ステータスバーを含まない画面領域を取得できます。今回はそれを使ってUITextViewオブジェクトを作成しています。

(3) テキストビューの表示に"Hello World"の文字列を設定しています。

(4) テキストの表示位置を中央に設定しています。

(5) 作成したテキストビューをビューコントローラが管理するビューとして設定します。

(6) loadView内で生成したオブジェクトはdeallocメソッド内で開放するようにします。

コードの実行

ここまで入力してコードを実行すると、以下のような画面が表示されます。

図3 実行結果
図3 実行結果

まとめ

今回は、main.mからコードを追っていくことで、iOSアプリケーションの実行の流れを解説しました。紹介したコードは、筆者のgithub上でも公開していますので、あわせて参考にしてくだください。

次回以降は、簡単なサンプルアプリケーションの作成を通して、iOSアプリケーション作成の様々な技法について学んでいきます。

おすすめ記事

記事・ニュース一覧