改訂本も終わって、ようやく開発ブログ復帰します。
とかいいながら、並列処理はうっちゃって地図画面の話。
ちょっと、後輩達と京都主催のiOSアプリコンペに参加する事にしまして…
京都まゆまろ杯
そのアプリで地図画面を使う事に決めたわけですよ。
グーグルマップ使いたいんだけど、まだThe Google Maps API Keyがグーグルから提供されないんだよね。
SDK自体は提供されてるんだが…
Google Maps SDK for iOS
てなわけで、とりあえずiOSのMapKitを使います。状況によってはグーグルマップに指し変えちゅーことで、できるだけ独立性を保ちながら作成してきましょう。

AppleのMap、まじ勘弁なわけなんだが…
ドリル本卒業者にもちょうどいいネタなんで、このネタは
テーマ:ドリル本 補完計画
でやっていきます。題して
iOSアプリで地図を出そう
それではいつものワンツスリーでプロジェクト作成~。
今回はSingle View Applicationテンプレートを利用する。

設定は、こんな感じで。特に説明はいらないっすね。
ARCはOnで。

PrefixにはKyoto Mapの頭文字を取ってKMを指定しますた。これでカスタムUIViewControllerクラス
が用意されるんで、こいつに地図画面を管理させ、最終的には本番アプリに組み込んで使います。
あとGitHabとの連携をさせてみたいのでgit使ってみます。

表示されるワークスペースウィンドウのナビゲーターエリアはこんな感じ。

で、テンプレのままRunさせるとこんな感じっす。Empty Applicationテンプレートと違って、グレーの背景なのねん。ただし、この背景はUIWindowじゃなくUIViewControllerのviewプロパティが画面全体を覆っていて、その背景色って状態です。

ここにマップビューを組み込むわけですが、Appleが提供してくれる地図用画面パーツクラスは
といいます。
資料はおなじみ日本語ドキュメントの「位置情報対応プログラミングガイド」です。
日本語ドキュメント
ドキュメントによるとMKMapViewクラスを使うにはフレームワークとして
の2つが必要みたい。
地図画面担当のMKMapViewはMapKit.frameworkに含まれてて、どの位置の地図を表示するか指定するための構造体定義やAPI(GPS操作なんかもある)がCoreLocation.framework側に含まれとります。
位置情報やGPSは必ずしも地図画面を必要とはしないので、こんなふうにフレームワークが分割されてるわけですな。さくっと組み込んでください。

組み込んだ後はこんな感じ。

これで準備はOKなんで、今度はKMViewControllerにMKMapViewを組み込みます。
考え方としてはKMViewControllerのviewプロパティそのものをMKMapViewクラスにする方法と、viewにMKMapViewインスタンスを貼付ける方法があるわけですが、私はお手軽な貼付ける方にします。
KMViewControllerのインスタンス変数として
てのを用意して、こいつでMKMapViewインスタンスを参照するようにします。まあ、readonly属性でプロパティにしてもいいけどね。まずは徹底的にカプセル化。なのでKMViewController.hのクラス宣言で
とはせずに、KMViewController.mのクラス拡張(@interface KMViewController ()…@end)側で宣言します。
このクラス拡張てのは、ヘッダーファイル側で公開したくないインスタンス変数やプロパティ、メソッドの宣言に使うもんです。
最近のXcodeのUIViewControllerテンプレートは、なにげに、このクラス拡張まで事前に用意してて、こいつ使ってくださいよ~的にアピールしてる。ステマ?
これがドリルでちょっと触れた隠蔽化のための工夫ってやつ。
詳しくは日本語ドキュメントの「Objective-C プログラミング言語」をあさりましょう。
インスタンス変数_mapViewが準備できたんで、あとは-viewDidLoadメソッドでインスタンス作成とviewへの貼付け。
Runすると~

てな具合でアメリカの地図表示。我がアメリカの技術力は世界いちぃいいいい。てわけでもないんだろうけど、何も指定しない場合、この表示っぽいっす。
で、これ表示して、京都までは手動でズルズルやってね~ってのは、あまりに不親切なわけで、京都市役所あたりを表示してやりましょう。
MKMapViewに表示する位置を指定してやるには、緯度、経度を使います。
緯度、経度にはCLLocationCoordinate2D構造体が用意されてて、latitudeメンバが緯度、longitudeメンバが経度です。
作成用に
てのもある。
でもって京都の緯度、経度は
緯度:35.0212466 経度:135.7555968
なので
と設定。あとはこの緯度、経度を中心にして、指定した範囲を表示しろとMKMapViewにメッセージを送ればいいわけで、そのための構造体が
です。こっちは緯度、経度それぞれの角度で範囲を指定(ドキュメントによると緯度1度は約111キロメートルだそうです)するんですが、さすがに感覚的にわからんので便利関数の
を使って、メートル単位で範囲を指定します。10km四方だとこんなかんじ。
こいつを_mapViewのregionプロパティに設定、つまり_mapViewにregion:kyotoregionメッセージを送ってやれば京都が表示されるわけっすね。
最終的な-viewDidLoadメソッドは次のようになります。
Runするとこんな感じ。

とりあえず今日はこれくらいにしといたらあということでKMViewController.mをコミット。
ま、コミットするタイミングは人それぞれ、好きにやってください。
ファイル選んでコンテキストメニューのSource Control→Commitっす。
コメント書き込んだらCommit 1 Fileね。

って、しまった、フレームワーク追加したからプロジェクトもコミットする必要があった、すなおにメニューからFile→Source Control→Commit…選ぶべきだった。
まあいい。とりあえず、プロジェクトもコミットしといた。
「なんすかコミットって?」な人は以前書いたgitの使い方「SCMでソース変更を管理する」を読んでみてね。
SCMでソース変更を管理する
次回は、自分の位置表示とピン投下。
------------
サンプルプロジェクト:KyotoMap.zip
とかいいながら、並列処理はうっちゃって地図画面の話。
ちょっと、後輩達と京都主催のiOSアプリコンペに参加する事にしまして…
京都まゆまろ杯
そのアプリで地図画面を使う事に決めたわけですよ。
グーグルマップ使いたいんだけど、まだThe Google Maps API Keyがグーグルから提供されないんだよね。
SDK自体は提供されてるんだが…
Google Maps SDK for iOS
てなわけで、とりあえずiOSのMapKitを使います。状況によってはグーグルマップに指し変えちゅーことで、できるだけ独立性を保ちながら作成してきましょう。

AppleのMap、まじ勘弁なわけなんだが…
ドリル本卒業者にもちょうどいいネタなんで、このネタは
テーマ:ドリル本 補完計画
でやっていきます。題して
iOSアプリで地図を出そう
それではいつものワンツスリーでプロジェクト作成~。
今回はSingle View Applicationテンプレートを利用する。

設定は、こんな感じで。特に説明はいらないっすね。
ARCはOnで。

PrefixにはKyoto Mapの頭文字を取ってKMを指定しますた。これでカスタムUIViewControllerクラス
KMViewController
が用意されるんで、こいつに地図画面を管理させ、最終的には本番アプリに組み込んで使います。
あとGitHabとの連携をさせてみたいのでgit使ってみます。

表示されるワークスペースウィンドウのナビゲーターエリアはこんな感じ。

で、テンプレのままRunさせるとこんな感じっす。Empty Applicationテンプレートと違って、グレーの背景なのねん。ただし、この背景はUIWindowじゃなくUIViewControllerのviewプロパティが画面全体を覆っていて、その背景色って状態です。

ここにマップビューを組み込むわけですが、Appleが提供してくれる地図用画面パーツクラスは
MKMapView
といいます。
資料はおなじみ日本語ドキュメントの「位置情報対応プログラミングガイド」です。
日本語ドキュメント
ドキュメントによるとMKMapViewクラスを使うにはフレームワークとして
MapKit.framework
CoreLocation.framework
CoreLocation.framework
の2つが必要みたい。
地図画面担当のMKMapViewはMapKit.frameworkに含まれてて、どの位置の地図を表示するか指定するための構造体定義やAPI(GPS操作なんかもある)がCoreLocation.framework側に含まれとります。
位置情報やGPSは必ずしも地図画面を必要とはしないので、こんなふうにフレームワークが分割されてるわけですな。さくっと組み込んでください。

組み込んだ後はこんな感じ。

これで準備はOKなんで、今度はKMViewControllerにMKMapViewを組み込みます。
考え方としてはKMViewControllerのviewプロパティそのものをMKMapViewクラスにする方法と、viewにMKMapViewインスタンスを貼付ける方法があるわけですが、私はお手軽な貼付ける方にします。
KMViewControllerのインスタンス変数として
_mapView
てのを用意して、こいつでMKMapViewインスタンスを参照するようにします。まあ、readonly属性でプロパティにしてもいいけどね。まずは徹底的にカプセル化。なのでKMViewController.hのクラス宣言で
MKMapView* _mapView;
とはせずに、KMViewController.mのクラス拡張(@interface KMViewController ()…@end)側で宣言します。
@interface KMViewController () {
MKMapView* _mapView;
}
@end
MKMapView* _mapView;
}
@end
このクラス拡張てのは、ヘッダーファイル側で公開したくないインスタンス変数やプロパティ、メソッドの宣言に使うもんです。
最近のXcodeのUIViewControllerテンプレートは、なにげに、このクラス拡張まで事前に用意してて、こいつ使ってくださいよ~的にアピールしてる。ステマ?
これがドリルでちょっと触れた隠蔽化のための工夫ってやつ。
詳しくは日本語ドキュメントの「Objective-C プログラミング言語」をあさりましょう。
インスタンス変数_mapViewが準備できたんで、あとは-viewDidLoadメソッドでインスタンス作成とviewへの貼付け。
@implementation KMViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
[self.view addSubview:_mapView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
[self.view addSubview:_mapView];
}
Runすると~

てな具合でアメリカの地図表示。我がアメリカの技術力は世界いちぃいいいい。てわけでもないんだろうけど、何も指定しない場合、この表示っぽいっす。
で、これ表示して、京都までは手動でズルズルやってね~ってのは、あまりに不親切なわけで、京都市役所あたりを表示してやりましょう。
MKMapViewに表示する位置を指定してやるには、緯度、経度を使います。
緯度、経度にはCLLocationCoordinate2D構造体が用意されてて、latitudeメンバが緯度、longitudeメンバが経度です。
CLLocationCoordinate2D
作成用に
CLLocationCoordinate2DMake
てのもある。
でもって京都の緯度、経度は
緯度:35.0212466 経度:135.7555968
なので
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(35.0212466, 135.7555968);
と設定。あとはこの緯度、経度を中心にして、指定した範囲を表示しろとMKMapViewにメッセージを送ればいいわけで、そのための構造体が
MKCoordinateRegion
です。こっちは緯度、経度それぞれの角度で範囲を指定(ドキュメントによると緯度1度は約111キロメートルだそうです)するんですが、さすがに感覚的にわからんので便利関数の
MKCoordinateRegionMakeWithDistance
を使って、メートル単位で範囲を指定します。10km四方だとこんなかんじ。
MKCoordinateRegion kyotoregion = MKCoordinateRegionMakeWithDistance(center,
10000.0, // 10km
10000.0);
10000.0, // 10km
10000.0);
こいつを_mapViewのregionプロパティに設定、つまり_mapViewにregion:kyotoregionメッセージを送ってやれば京都が表示されるわけっすね。
_mapView.region = kyotoregion; // アニメーション抜き
最終的な-viewDidLoadメソッドは次のようになります。
- (void)viewDidLoad
{
[super viewDidLoad];
_mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
[self.view addSubview:_mapView];
// 京都 latitude:35.0212466 longitude:135.7555968
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(35.0212466, 135.7555968);
MKCoordinateRegion kyotoregion = MKCoordinateRegionMakeWithDistance(center,
10000.0, // 10km
10000.0);
_mapView.region = kyotoregion; // アニメーション抜き
}
{
[super viewDidLoad];
_mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
[self.view addSubview:_mapView];
// 京都 latitude:35.0212466 longitude:135.7555968
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(35.0212466, 135.7555968);
MKCoordinateRegion kyotoregion = MKCoordinateRegionMakeWithDistance(center,
10000.0, // 10km
10000.0);
_mapView.region = kyotoregion; // アニメーション抜き
}
Runするとこんな感じ。

とりあえず今日はこれくらいにしといたらあということでKMViewController.mをコミット。
ま、コミットするタイミングは人それぞれ、好きにやってください。
ファイル選んでコンテキストメニューのSource Control→Commitっす。
コメント書き込んだらCommit 1 Fileね。

って、しまった、フレームワーク追加したからプロジェクトもコミットする必要があった、すなおにメニューからFile→Source Control→Commit…選ぶべきだった。
まあいい。とりあえず、プロジェクトもコミットしといた。
「なんすかコミットって?」な人は以前書いたgitの使い方「SCMでソース変更を管理する」を読んでみてね。
SCMでソース変更を管理する
次回は、自分の位置表示とピン投下。
------------
サンプルプロジェクト:KyotoMap.zip