Hatena::ブログ(Diary)

div1に上がりたいkeitanxkeitanの日記

2011-01-16 Weather Utility

天気予報アプリ

| 17:43

livedoorの無料の天気予報APIWeather Hacks」を使った天気予報アプリを作った。

今回のトピックは

  1. データベースの利用
  2. WebサービスAPIの利用
  3. ユーティリティアプリっぽい「くるっ」とした動き

の3本で。

データベースの利用

前回作成したDiarySystemと同様に、SQLiteラッパークラスであるFMDBを利用する。更に、今回は発展させてこちらの記事を参考にして、DAO(Data Access Object)デザインパターンを採用して、再利用可能な箇所は出来る限り抽出してみた。

今回利用するデータベースこちらの記事にあるように、150弱の都市のコードを管理するものである。各レコード都市コード(code)、都市名(name)、地域(region)、都道府県(prefecture)というカラムを持っていて、実際のアプリケーションでは住んでいる都市を地域→都道府県→都市名という順番でテーブルビューを利用して選択する。

f:id:keitanxkeitan:20110116171708p:imagef:id:keitanxkeitan:20110116171707p:image


地域と都道府県をSELECTする部分のソースコードは以下の通り。

- (NSMutableArray *)selectRegion {
	NSMutableArray *result = [[[NSMutableArray alloc] initWithCapacity:0]
							  autorelease];
	FMResultSet *rs = [db_ executeQuery:[self setTable:@"SELECT DISTINCT region FROM %@"]];
	
	while ([rs next]) {
		TbCity *tc = [[TbCity alloc]
					  initWithCode:0
					  name:nil
					  prefecture:nil
					  region:[[rs stringForColumn:@"region"] retain]];
		[result addObject:tc];
		[tc release];
	}
	[rs close];
	return result;
}

- (NSMutableArray *)selectPrefectureWithRegion:(NSString *)region {
	NSMutableArray *result = [[[NSMutableArray alloc] initWithCapacity:0]
							  autorelease];
	FMResultSet *rs = [db_ executeQuery:[self setTable:@"SELECT DISTINCT prefecture FROM %@ WHERE region = ?"], region];
	
	while ([rs next]) {
		TbCity *tc = [[TbCity alloc]
					  initWithCode:0
					  name:nil
					  prefecture:[[rs stringForColumn:@"prefecture"] retain]
					  region:nil];
		[result addObject:tc];
		[tc release];
	}
	[rs close];
	return result;
}

150弱の都市名があるので、地域(region)と都道府県(prefecture)は重複しています。そのため、"SELECT DISTINCT"で重複要素は表示しないようにしています。

また、regionやprefectureをセットするところでretainしていますが、これをしないと、テーブルビューに表示する際にautoreleaseされてしまうことがあり、エラーの原因になります。

WebサービスAPIの利用

今回利用したのは無料の天気予報APIであるWeather Hacksです。発行すべきクエリはこんな感じ。

http://weather.livedoor.com/forecast/webservice/rest/v1?city=113&day=tomorrow

cityは先程のデータベースから取得できる都市コードで、dayはtoday(今日)、tomorrow(明日)、dayaftertomorrow(明後日)が指定できます。上のリンクをクリックするとわかりますが、このクエリを発行すると天気情報がXMLで取得できるので、XMLパーサーが必要です。

XMLパースにはNSXMLParserを利用しました。こちらの記事を参考にして、NSXMLParserをコントロールするクラスを作成しました。

ユーティリティアプリっぽい「くるっ」とした動き

今回作るアプリケーションは、Weather Utilityという名前の通りユーティリティアプリです。そしてユーティリティアプリと言えば、infoボタンをタッチしたときの「くるっ」とした動きです。これを実現します。

まず、メイン画面はこんな感じになります。

f:id:keitanxkeitan:20110116173244p:image

このメイン画面の右上のinfoボタンをタッチすると、先ほど作成したテーブルビューの画面に移動します。

これは、infoボタンのアクションに次のようなメソッドを指定すると実現できます。

- (void)showInfo:(id)sender {
	UINavigationController *navigationController =
	[[UINavigationController alloc] initWithRootViewController:[[RegionTableViewController alloc] init]];

	navigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
	[self presentModalViewController:navigationController animated:YES];
	[navigationController release];
}

テーブルビューはナビゲーションコントローラーでドリルダウンしているので、UINavigationControllerのルートビューに地域表示用のテーブルビューを指定したものを作成して、modalTransitionStyleとしてUIModalTransitionStyleFlipHorizontalを指定します。そしてこれを、現在のビューコントローラーのpresentModalViewControllerメソッドで表示します。このメソッドはピッカービューの表示などでも利用します。

設定画面から戻るためには、移動先のビューコントローラーでdismissModalViewControllerAnimatedメソッドを使います。

こちらの記事を参考にしました。

トラックバック - http://d.hatena.ne.jp/keitanxkeitan/20110116/1295167422