iPhoneアプリ開発日記
iPhoneアプリの開発に関するあれこれ
iPhoneアプリの開発に関するあれこれ
11月 6th
1x歳シリーズの新刊『15歳からはじめるiPhoneわくわくゲームプログラミング教室』が2011年11月15日に発売されます。執筆は大阪電気通信大学 デジタルゲーム学科の講師をされている沼田哲史先生です。
http://www.amazon.co.jp/dp/4899773005/
※当社(リブロワークス)は編集・制作のみを担当しているので、この自習室の対象とはなりません。ご了解ください。
昨年末に出版社のラトルズ様から、1x歳シリーズのiPhone版の依頼を受けたものの、社内での執筆は難しいと判断して、執筆をお願いできる方を探した結果、沼田先生にご快諾いただきました。
その後、iPhone4S(当時はiPhone5が6月に刊行されるという噂でした)の販売日に合わせて刊行日を数ヶ月延ばすこととなり、iOS5のRC版に合わせて最終調整を加えて、ようやく刊行にいたりました。Apple製品はとにかくギリギリまで情報解禁しないので、そこが一番ハラハラさせられた点です。
Objective-Cは難解で取っつきにくいイメージがあったのですが、沼田先生はとてもシンプルでわかりやすく解説されています。サンプルコードを拝見していて、「iPhoneゲームがこんな短いコードで作れるのか」と大変驚かされました。もちろん1x歳シリーズのコンセプトどおり、プログラミングやゲーム開発の経験のない方を対象としたゼロからの解説となっております。開発環境のXcode4はMac OS X 10.7ユーザーなら無料で利用できます(10.6ユーザーはiOS Developer Programへの有料登録が必要となります。これはApple社の方針なので、こちらではどうにもならない点です)。
一般書店やAmazonなどのネット書店で販売されますので、ぜひご一読ください。
2月 21st
よくよく考えて見れば、操作用のボタンは普通にUIButtonで追加すればいいだけのことでした。
左右のどちらかのボタンを押すと移動、同時に押すとジャンプします。この操作方法は「Shift」というiPhoneゲームのまねです。
maori-iphone_src1102b.zip(要XCode4)
2月 12th
前回ひっくり返った状態になっていた画面は、ちょちょいといじって解決。
そこは大したことなかったのですが、タッチ操作をキーとして渡す部分が思ったより簡単にはいかんようです。
とりあえず途中段階ですが公開しておきます。
2月 7th
Windows用に作成したスーパーマリオ風アクションゲームを移植する計画はちょっとずつ進めていて、昨夜ようやくすべてのビルドエラーが消えて実行可能な状態になりました。
一度も実行せずにエラーを潰していたので、実行するのは数週間ぶりです。
でも、ちゃんと動いてるっぽいですね……。一覧の「MaoriBros」をタップするとゲーム実行開始です。
うまくいった! と思いきや、あらら……
1月 23rd
ここ2回ほどBox2DのiPhone版をいじっていたのですが、バージョンが2.0.2と古いので色々と入れ替えて2.1.2にバージョンアップしました。
ダウンロード(Box2D_2.1.2.iPhone.zip)
※XCodeのプロジェクト設定(.xcodeproj)は「Build」→「iPhone」→「Box2D」フォルダの中にあります。
少々手間取りましたが、終わってみるとそんなにたいした作業でもありません。
PC版Box2D 2.1.2のソースコードを落としてきて、Box2D本体の部分とTest関連のソースコードを入れ替え、プロジェクトにドラッグ&ドロップして更新します。元のiPhone版ではBox2D本体のソースコードが「Sourceフォルダ」に入っていたのですが、これをBox2Dという名前に変えます。さらにプロジェクト設定を開いて「ヘッダ検索パス」に「../../../」を設定します。
後はiPhoneTest.h/mm、GLES-Render.h/mm、iPhoneTestEntries.mmを、PC版のソースコードとにらめっこしながら編集して完成です。
ついでに「Box2DOrientation.h」というファイルを足し、その中の「BOX2DVIEW_LANDSCAPE」という#defineマクロによって縦画面固定と横画面固定を切り替えできるようにしました。
実機テストも問題なくパス。これを元に作ったアプリがApp Storeで売れるかどうかはわかりませんが……(テーブルビュー周りで使ってるメソッドが古い的な警告が表示されていたので、そこは引っかかりそうです)。
1月 17th
iPhone向けBox2Dの画面は縦向き固定なので、これを横向き固定に変更します。ちょっとハマリそうだなとは思っていましたが、予想通りハマリました。
横向きで起動するだけなら、plistにUISupportedInterfaceOrientationsを追加して向きを横に限定すればいいのですが……。
これだけだと縦画面のまんま横向きになります。
Appleのガイドラインなどを見ると、この後UIViewControllerにShouldRotate~といったメソッドを書くように説明されているのですが、このプロジェクトにはビューコントローラがありません。
結局、こんなになったりこんなになったりと、試行錯誤が続き……
数時間かかってようやくこの記事の先頭の画像にたどり着いたわけです。画面を回すだけのことでこんなに苦労するのはイヤですねぇ。
でも、これでようやくiPhoneでまともな2Dゲームが作れる環境が手に入ったようです。後はC++で書けるわけですからね(ちなみにOpenGL ESはObjective-CではなくC言語の文法で使います)。
では、途中経過は省いて、どうやればいいのかだけを説明します。
1月 16th
前回はKarakuri Frameworkを使って、C++でiPhone用のアプリを開発できるという話をしましたが、「iPhone用のBox2Dサンプル」を使ってもほぼC++だけでアプリ開発ができることがわかりました。幸いWindows上でのBox2Dを触った経験があるので、そのときに作ったサンプルを移植することを目指してみます。
今回はまず、iPhone版Box2Dがどういう構造になっているのかを分析していきます。
iPhone版Box2Dはここからダウンロードできます。「Download GNU tarball」というリンクをクリックしてください。Box2Dのバージョンは2.0.2と若干古いのですが、画面表示にOpenGL ESを使い、タッチ操作や加速度センサーにも対応しているので、ゲームの基本形として使うことができます。
http://box2d.svn.sourceforge.net/viewvc/box2d/trunk/
ダウンロードしたファイルを解凍し、その中の「Box2D.xcoredeproj」ファイルを探してXCodeで開き、SDKバージョンなどの更新を行ってビルドすると次のようなプログラムが表示されます。一覧から実行したいテストを選んで実行。ドラッグや傾きで操作できます。ダブルタップで一覧に戻りますが、うまく戻らないこともありました。その辺はどうせ使わないので気にしなくてもいいでしょう。
11月 21st
また、前の日記から時間が経ってしまいました。なんでこうなったのかなと考えて見ると……
まぁ、よくありがちな話ですね。
これでは時間がもったいないので、根本的に方針を変えることにしました。
そこで、Objective-Cやインターフェースビルダーを使わずに済み、自分が知っているプログラム言語(C、C++、Java、ActionScript、C#、JavaScript、PHPのいずれか)が使えて、それでいてさらなる出費やパフォーマンス低下をまねかないiPhoneアプリの開発方法はないものかと探していたところ、Karakuri Frameworkというものを見つけました。
このKarakuri Frameworkは、C++でiPhone/iPad/OSX用のゲームが作れるフレームワークです。ダウンロードしたインストーラーを実行すると、XCode用のテンプレートとKarakuri BOXというリソース編集用アプリがインストールされます。
おおー、完全にC++だ! 同じXCodeの画面なのにすっごいホッとしました(笑)。
テンプレートがそのままゲームのサンプルになっていて、デバッグ実行するとシミュレータでゲームが実行されます。
ドキュメントをざっと眺めた感じでは、C++の基礎知識さえあればかなり簡単に使えそうです。
ゲームのためのフレームワークですが、1024×1024ピクセル以内のテクスチャ描画ができるので、それを使えば強引にマンガビューワを作ることもできるでしょう。足りない部分はiOSのAPIで補うとして……。
9月 21st
前回更新からだいぶ日が経ってしまいましたが、めげずに更新を続けます。
今回は「テーブルビューコントロール(UITableViewController)」を追加し、ZIPファイルの一覧を表示します。テーブルビューというのは簡単にいえば「表」のことです。iPodのプレイリスト一覧などに使われているものですね。
iOSのテーブルビューの使い方は、他のプラットフォームのものと結構違います。他ではテーブル用のオブジェクトを作成し、そこにアイテムを追加していって、後のことはおまかせというものが多いと思うのですが、iOSのテーブルビューでは……
といった具合に表示も自分でやってあげなければいけません。
8月 12th
前回の記事の続きです。
今回はInterfaceBuilderで作成したUIと、XCodeで書いているコード部分をリンクさせます。
おおまかな作業内容は、
となります。ついでに起動時にリソース内のsamplebook.zipを、アプリのドキュメントフォルダにコピーする処理も書きます。

AppDelegate_iPhoneクラスのヘッダファイルにプロパティの宣言を追加します。「@interface」~「@end」までがクラス宣言です(@interfaceはJavaなどで言うインターフェースとは別物です。Objective-Cでインターフェースに相当するものはプロトコルといいます)。
#import <UIKit/UIKit.h>
#import "AppDelegate_Shared.h"
@interface AppDelegate_iPhone : AppDelegate_Shared {
//メインのナビゲーションコントローラ(MainWindow_iPhone.xibで定義)
IBOutlet UINavigationController* myNavigationController;
}
@property (nonatomic, retain) IBOutlet UINavigationController *myNavigationController;
@end
6行目が実際にデータを記憶するメンバ変数の定義、9行目がプロパティの宣言です。Objective-Cの型は基本的にC言語のポインタなのですね。
@propertyの後の「(nonatomic, retain)」はプロパティの属性の指定です。nonatomicはプロパティをスレッドセーフに「しない」指定だそうで、おそらくそのほうが速いとかそういうメリットがあるのでしょう。retainは、プロパティに代入するときに「オブジェクトのretainメソッドを呼び出すことを要求する」指定だそうです。
retainはObjective-Cのメモリ管理を行うメソッドで、オブジェクトの参照カウントを1増やします。参照カウントを減らしたいときはreleaseメソッドを呼び出し、カウントが0になるとオブジェクトは消滅します。理屈はそれほど難しくはないんですが、APIによっては中でretainやreleaseしているものがあるようで、その辺の癖がわかっていないとretainしすぎてメモリリークが起きたり、オブジェクトが消滅してしまっていてアプリが落ちたりすることもあります。
さて、プロパティの話に戻ります。他の言語と同じくプロパティに対してはsetterとgetterを書かなければいけないのですが、代入以外のことをしないのであれば、クラス定義の中に「@synthesize プロパティ名;」と書くと自動的に補完してくれます。
Objective-Cのクラス定義は「@implementation~@end」の間に書きます。
#import "AppDelegate_iPhone.h" @implementation AppDelegate_iPhone @synthesize myNavigationController; #pragma mark - #pragma mark Application lifecycle
@synthesizeを使わない場合は、「プロパティ名」メソッド(getterになる)や「setプロパティ名」メソッド(setterになる)を書きます。メソッドの名前だけで判断しているようなので、うっかり書かないよう気を付けないといけませんね。
IBOutlet付きのプロパティを定義したら、InterfaceBuilderに戻ってプロパティとUI部品の関連づけを行います。コードを修正しただけではInterfaceBuilder側でプロパティ名が出てこないことがあるので、一回「command+B」を押してビルドしたり、XIBファイルを閉じてXCodeから開き直したりするといいようです。
書類ウィンドウで「Navigation Controller」を選び、InspectorウィンドウのConnectionsタブ(左から2番目)をクリックします。そして、「New Referencing Outlet」の○を書類ウィンドウの「App Delegate」までドラッグします。
プロパティ名が表示されたらそれをクリックします。
これでmyNavigationControllerプロパティが、AppDelegate_iPhone.xibファイル内のナビゲーションコントローラとリンクします。上書き保存してからXCodeに戻ってください。
ちなみに、このXIBファイルにはWindowという部品もありますが、こちらはプロジェクト作成時点でAppDelegate_Sharedクラスのwindowプロパティとリンクされています。
「iOS Application Programing Guide」によると、iPhoneアプリが起動するときは、まず「didFinishLaunchingWithOptions」メソッドが呼び出され、次に「applicationDidBecomeActive」メソッドが呼び出されるとのこと。iOS4でマルチタスク(高速スレッド切り替えと呼ぶべき?)に対応したので、起動後に他のアプリから切り替えたときは、前者は呼び出されず、後者だけが呼び出されるそうです。
(Programing Guideより引用)
リソースファイルをドキュメントフォルダにコピーする処理は起動時に一回だけやればいいので、applicationDidBecomeActiveメソッドに書きます。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[window makeKeyAndVisible];
//リソースのZIPファイルのパスを取得
NSString *filePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"samplebook.zip"];
NSLog(@"resoruce=%@", filePath);
//ドキュメントフォルダの場所を取得
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docpath = [paths objectAtIndex:0];
NSString *destPath = [docpath stringByAppendingPathComponent:@"samplebook.zip"];
//リソースをドキュメントフォルダにコピー
NSFileManager *fileman = [NSFileManager defaultManager];
NSError *error;
[fileman copyItemAtPath:filePath toPath:destPath error:&error];
//ナビゲーションコントローラを追加
[window addSubview:myNavigationController.view];
return YES;
}
3行目までと21行目以降は最初からあるものなので、削ってしまうとちゃんと動作しなくなると思われます。
6行目で「samplebook.zip」という名前のリソースファイルのパスを取得し、NSString型変数filePathに記憶します。
10~11行目でアプリのドキュメントフォルダのパスを取得し、コピー先のファイルパスを作成します。
15行目でNSFileManagerのオブジェクトを取得し、copyItemAtPathメソッドでコピーします。
20行目はInterfaceBuilderで作成したナビゲーションコントローラを、メインウィンドウの上に配置する処理です。コントローラを直接置くことはできないので、その上のビューをviewプロパティで取り出して配置しています。
iOSのAPIについては、ネット上に日本語訳された情報が多数あるのですが、必ず公式のリファレンスライブラリも合わせて見ることをお奨めします。英語ですが「このメソッドはもう推奨しないので、××を使ったほうがいい」といった、最新の注釈が書かれているからです。
・iOS Reference Library(英語)
http://developer.apple.com/iphone/library/navigation/
・日本語翻訳された公式ドキュメント
https://developer.apple.com/jp/iphone/library/japanese.html
ツールバーのリストから「Simulator – 4.0 | Debug」を選び、「ビルドと実行」ボタンをクリックします。実行を中断したいときは隣の「タスク」ボタンをクリックします(どうして「タスク」という名前なのでしょうね?)。
![]()
iPhoneシミュレータが起動して、アプリの画面が表示されたら成功です。
FinderでiPhoneシミュレータの作業用フォルダを見ると、ちゃんとDocumentsフォルダにsamplebook.zipがコピーされているはずです。
作業用フォルダは、「ユーザー」→「ライブラリ」→「Application Support」→「iPhone Simulator」→「バージョン番号」→「Applications」→「アプリのGUID」にあります。
今回のソースコードは以下からダウンロードできます。なお、「samplebook.zip」は市販マンガをスキャンしたものなので除いています。前々回の記事のリソースファイルに関する話を参考に、自分で追加してください。
余談ですが、実は最後の実行時点でトラブルが起きました。コードには問題がないはずなのに、アプリを起動してもナビゲーションバーが表示されません。
色々調べたところ、原因はInterfaceBuilderで「File’s OwnerとApp Delegateのリンクが切れていた」ことでした。これが切れるとAppDelegate_iPhoneクラスのメソッドが呼び出されません。
プロジェクト作成時にリンク済みになっているはずなので、画面キャプチャを撮るときに誤ってクリックしてしまったのでしょう。
iPhoneアプリ開発では、初期状態で与えられるリンク設定やコードファイルの記述を不用意にいじると簡単に正常動作しなくなってしまいます。自分で作成したものでないだけに、原因を探すのは大変です。