夏休み自由研究 - iPhoneでいきもの図鑑を作る

カテゴリ
ブックマーク数
このエントリーを含むはてなブックマーク はてなブックマーク - 夏休み自由研究 - iPhoneでいきもの図鑑を作る
このエントリーをはてなブックマークに追加
おつかれサマーです。開発部モバイルGの井上です。ケータイライブドアの各サービス、iPhoneアプリ開発等を担当しています。

さて、夏休みもあと数日になりました。全国の小学生の皆さんは、夏の宿題に追われている頃ではないでしょうか。 え、まだ手をつけてない? 大丈夫、たいていそんなものです。これからが勝負ですね。

たとえば昆虫採集なんか、比較的お手軽でよいんじゃないでしょうか。近くの公園で虫を捕まえて、お中元の箱かなんかに並べて学校に持っていけばオッケー。 ただ、研究テーマとしては古典的すぎて今さらという感じですね。虫をピンで刺すのもかわいそうだし。

そこで今回は、iPhoneアプリでいきもの図鑑を作ってみます。エコかつIT、スマートですね。 先生もびっくり、クラスのあの子にも超アピールです。

iPhoneアプリは、作り込みをはじめると時間がかかりますが、簡単なアプリなら工作感覚で手軽に組むことも可能です。 カメラやGPSも、最小限のコードで利用できるAPIが用意されています。 カメラでいきものの写真を撮ると、位置情報つきで一覧できて、地図にプロットできる、というライブな図鑑アプリを作ってみます。

プログラムなんかできない? 問題ナッシングです。英語がちょっと読めればプログラムもだいたい読めます。

それでは始めてみましょう。


■必要なもの


○開発機
Mac(9.4万円〜)
ノートでもデスクトップでも可。

○開発ソフト
XCode(無料)
アップルのサイトからDLできます。UIデザインをするInterfaceBuilderと、動作確認用のiPhoneシミュレータも同梱されています。

○できれば用意したいもの
iPhone か iPod Touch(2.5万円〜)
iPhone Developer Program($99)
シミュレータである程度代用できます。本気で開発するときにはお父さんに貸してもらいましょう。

MacでXCode、InterfaceBuilder、iPhoneシミュレータを立ち上げ、実機(ある場合)を接続したら、準備は完了です。


■画面図を描く


まずアプリ画面の全体図をかんたんに描いてみます。チラシの裏でオッケーです。 ボタンやバーの配置、ナビゲーションなどを、途中で迷わないように決めておきます。

02_01

今回は、いきものの写真を撮り、マップに表示させるということで、大きく画面は2つです。 下にタブバーを置いて、カメラとマップをそれぞれ左右のタブにあてました。 写真を撮るときには、カメラビューの右上のボタンを押すと、カメラユニットが立ち上がります。

全体の画面が決まったら、Macを立ち上げて製作に入ります。


■ビューをデザインする


Xcodeで新規プロジェクトを作ってアプリを作っていきます。 メニューから、ファイル > 新規プロジェクト > iPhone OS > Tab Bar Application を選択すると、タブバーを使ったアプリケーションのスケルトンが作られます。

03_01

項目が山ほどあってイヤンな感じですが、とりあえず左カラムのResourcesとClassesのフォルダに注目です。

Resourcesの中に、FirestView.xib・SecondView.xibというファイルがあります。それぞれ、タブで切り替わる2つの画面デザインを定義するファイルです。InterfaceBuilderで編集します。 Classesの中にあるのが、動作のロジックを記述していくプログラムファイルです。

プログラムの処理は画面単位でまとめます。FirstViewでの処理は、FirstViewController.mに書きます。同名の.hというファイルがありますが、これはヘッダファイルといって、変数やメソッドの定義を書くところです。

このスケルトンはもうアプリとして動きます。「ビルドと実行」という緑のボタンを押してみてください。 シミュレータが立ち上がり、アプリが起動します。タブバーで2つの画面を切り替えられます。

03_02

このひな形をもとに、ビューのデザインやプログラムコードを追加して、アプリを作っていきます。

まず、FirstViewとSecondViewにカメラのボタンと地図を配置してみましょう。

FirstView.xibをダブルクリックすると、InterfaceBuilderで画面のプレビューがでてきます。 このプレビューにバーやボタン、画像や地図などを配置することで、画面をデザインすることができます。

さまざまなパーツが並んだ LibraryペインからUIをドラッグ&ドロップします。レゴの組み立ての感覚ですね。 パーツの色・サイズ・アイコンの種類などは、View Attributesペインで設定できます。

04_01
04_02

続いてSecondViewにはバーとマップを配置します。

04_03

マップと位置情報を使うためには、追加の設定が必要です。 Xcode左カラムのFrameworkフォルダをCtrl+クリックして、「追加 > 既存のフレームワーク…」から MapKit.frameworkとCoreLocation.frameworkを選んでください。

1回保存して、緑のボタンでビルドしてみましょう。

04_04 04_05

ボタンやマップが出てきます。 この状態でもう、マップをスクロールしたり拡大することもできます。

1行もコードを書いてませんが、それらしくなってきましたね。


ロジックを書く


いよいよプログラミングです。 何をしたらどうなるかというロジックの部分を、XCodeの中に書いていきます。

今回必要なプログラムの処理は4つです。意外と少ないですね。

ファーストビューの処理
・カメラボタンを押したとき → カメラが立ち上がって写真が撮れる
・写真が撮れたとき → 写真の画像データ、および位置情報・タイトル・日付のデータを保存する
・データがあるとき → テーブルに画像とタイトルの一覧を表示する

セカンドビューの処理
・データがあるとき → マップに画像と位置を示すピンを表示する

それぞれ数十行程度の簡単なプログラムです。 順番に見ていきます。

まずカメラボタンを押したときのコードです。分からなくてもいいので、ざっと見てみてください。

- (IBAction)pushedCameraButton {
	
	self.imagePickerController = [[[UIImagePickerController alloc] init] autorelease];
	self.imagePickerController.delegate = self;
    self.imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
	self.imagePickerController.showsCameraControls = YES;
	[self presentModalViewController:self.imagePickerController animated:YES];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
	
    UIImage *takenPhoto = [info valueForKey:UIImagePickerControllerOriginalImage];
	[self dismissModalViewControllerAnimated:YES];
	[self performSelector:@selector(showCameraInputView:) withObject:takenPhoto afterDelay:1.0];
}

プッシュカメラボタンとあって、そのあとカッコでくくられてますね。 ボタンを押したら、カッコの中の処理が走るということです。 イメージピッカーというのがiPhoneでのカメラ機能を受け持つAPIです。 いくつか設定をして、最後の presentModalViewController で画面に表示させています。カメラの画面がにゅっと下から出てくることになります。

ふたつめのカッコで、シャッターが押されたときの画像が返ってきます。takenPhoto というのが画像データを表します。

ここでは、タイトルを入力するフォームに takenPhoto を渡しています。フォーム上でタイトルなどを入れて、保存ボタンを押すと、データが一式保存されます。

次に保存するところのコードです。

タイムスタンプ + 乱数のidを決めて、その名前で写真のpngファイルを保存、さらにid・日時・位置情報・タイトル・ノートをディクショナリーと呼ばれるデータホルダーの中に突っ込んで、それを保存しています。ちょっと長いですが、だいたいの流れが分かればオッケーです。

- (IBAction)save {
	
	NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
	NSDate *date = [NSDate date];

	// ID
	srand(time(nil));
	int num = rand() % 100;
	int sec = (double)[date timeIntervalSince1970];
	NSString *anId = [NSString stringWithFormat:@"%d%d", sec, num];
	[dictionary setObject:anId forKey:@"id"] ;
	
	// 位置情報
	CLLocation *location = [locationManager location];
	if (!location) return;
	CLLocationCoordinate2D coordinate = [location coordinate];
	[dictionary setObject:[NSNumber numberWithDouble:coordinate.latitude] forKey:@"latitude"];
	[dictionary setObject:[NSNumber numberWithDouble:coordinate.longitude] forKey:@"longitude"];
	
	// 日付
	[dictionary setObject:date forKey:@"date"];
	
	// タイトルとノート
	[dictionary setObject:titleTextField.text forKey:@"title"];
	[dictionary setObject:noteTextView.text forKey:@"note"];
	
	IkimonoAppDelegate *appDelegate = (IkimonoAppDelegate *)[[UIApplication sharedApplication] delegate];
	
	// 画像の保存
	NSData *pngPhoto = UIImagePNGRepresentation(photo);
	[pngPhoto writeToFile:[NSString stringWithFormat:@"%@/photo/%@@2x.png", [appDelegate documentPath], anId] atomically:NO];
	
	NSData *pngTumbnail = UIImagePNGRepresentation(thumbnail);
	[pngTumbnail writeToFile:[NSString stringWithFormat:@"%@/thumbnail/%@@2x.png", [appDelegate documentPath], anId] atomically:NO];
	
	// Dictionaryの追加
	[appDelegate.ikimonoArray addObject:dictionary];
	[appDelegate saveArray];
	
	[self dismissModalViewControllerAnimated:YES];
}

データが保存できればあとは表示するだけですね。マップへのピンの表示は、アノテーションというのを作って、そこに先ほどのディクショナリーからタイトルや位置情報をセットしてやって、マップに渡してやります。

- (void)addAnnotation {
	NSDictionary *dictionary = [appDelegate.ikimonoArray objectAtIndex:i];
	Annotation *annotation = [[Annotation alloc] init];
	annotation.latitude = [dictionary objectForKey:@"latitude"];
	annotation.longitude = [dictionary objectForKey:@"longitude"];
	annotation.title = [dictionary objectForKey:@"title"];

	NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
	[outputFormatter setDateFormat:@"MM/dd HH:mm"];
	annotation.subtitle = [outputFormatter stringFromDate:[dictionary objectForKey:@"date"]];
	[self.mapAnnotations addObject:annotation];
	[self.mapView addAnnotation:annotation];	
}

という感じで、必要なプログラムを追加していきます。

05_01

処理が書けたら、InterfaceBuilderで配置したパーツと、プログラムを結びつけます。 InterfaceBuilderのFile's OwnerをCtrl+クリックすると、先ほどのpushedCameraButtonがでてくるので、それをカメラのボタンにドラッグしてやります。

これでデザインとロジックが結合したことになります。 こんな感じでInterfaceBuilderとXCodeを行ったりきたりしていると、アプリがだんだん出来あがってきます。

さて、最後に仕上げです。 アプリ名やアイコン画像を設定します。アイコンはきれいなのを作りたいものです。 絵のうまい友だちに描いてもらうといいですね。

自分はあまりうまくないです。

05_02

完成!!!


いきものを撮影


では、近所の小金井公園にいきものを探しに行ってみます。 小金井公園は79万平米、東京都で2番目に広い公園です。園内には広い芝生や雑木林、池などもあります。

草むらの陰にセミの抜け殻を発見!

06_01

民家の塀のアサガオ。

06_02

池にはカメ。

06_03

オケラを見つけてしまいました。こいつはレアです。

06_04

図鑑らしくなりました。 マップのタブを確認すると、見つけた場所にピンが落ちてます。

06_06 06_05

ばっちりですね!

写真を撮りまくって、自分だけのいきもの図鑑を作ってみてください。 ネットワーク機能を追加して、友だちと共有しても楽しそうです。

といういわけで、夏の自由研究で作ってみたいちょっとしたiPhoneアプリのススメでした。

iPhoneプログラミングはMac1台から始められますし、GPS・カメラ・加速度センサーといった最新のモバイル機能を手軽に利用できます。 工作スピリッツ燃える小中高生の皆さんは是非チャレンジしてみるといいと思います。もちろん、大人の自由研究というのもアリですね。

今回のサンプルコードはこちらからダウンロードできます。
レスポンス
コメント(0)
トラックバック(0)

このエントリーをはてなブックマークに追加