最近、iOS位置情報プログラミングという本を買って読んでいます。
この本を読んで、iOS 6.1からMap Kitにローカル検索機能が追加されたと知り、さっそくその性能を試してみました。(ここでローカル検索と呼んでいるのは、文字列から駅や飲食店などを検索できる検索機能のことです)
実装方法
ローカル検索には次のクラスを使用します。
- MKLocalSearch
- MKLocalSearchRequest
- MKLocalSearchResponse
まずは MKLocalSearchRequest
インスタンスを生成し、検索文字列、検索範囲をセットします。
MKLocalSearchRequest *request =
[[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = searchBar.text;
request.region = _mapView.region;
次に、このインスタンスから MKLocalSearch
インスタンスを生成します。
MKLocalSearch *search =
[[MKLocalSearch alloc] initWithRequest:request];
これでローカル検索の準備ができました。さっそく startWithCompletionHandler
メソッドを使って検索してみます。
[search startWithCompletionHandler:
^(MKLocalSearchResponse *response, NSError *error)
{
for (MKMapItem *item in response.mapItems)
{
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = item.placemark.coordinate;
point.title = item.placemark.name;
point.subtitle = item.placemark.title;
[_mapView addAnnotation:point];
}
[_mapView showAnnotations:[_mapView annotations] animated:YES];
}];
実行結果は blocks 内で受け取ることができます。第1引数の MKLocalSearchResponse
が検索結果で、第2引数にはエラー情報がセットされます。MKLocalSearchResponse
クラスの mapItems
プロパティが配列形式になっており、検索にヒットした分だけ MKMapItem
形式で格納されています。この例では、検索結果を順に取り出して MKMapView
に表示しています。
ちなみに、実装中に知ったのですが、iOS 7から次の便利なメソッドが使えるようになっていました。
// Position the map such that the provided array of annotations are
// all visible to the fullest extent possible.
- (void)showAnnotations:(NSArray *)annotations
animated:(BOOL)animated;
第1引数に MKAnnotation
(赤いピン等)の配列を指定すると、その全てが地図上に表示されるように、自動で縮尺率を調整してくれます。今までだと、これを実現するためには一番端のピンを自分で求める必要があったので、だいぶ楽になりそうですね。
実行結果
まずは「渋谷駅」で検索してみました。
ちゃんと検索できましたね!
次は「吉野家」で検索してみました。
ちゃんとヒットしたのですが、なぜか1件しか返ってきません。全国に吉野家は何件もあるはずなのに不思議ですね。
今度は、割と新しい建物である「ヒカリエ」を検索してみました。
茨城県の「光」という地域がヒットしました。。
そして最後に「スカイツリー」で検索してみましたが、結果件数はゼロでした。
使ってみた感想
最初に紹介した書籍でも書かれていましたが、日本での検索結果はまだ十分とは言えないと思いました。今後、より充実したエリア情報が検索できるようになることを期待しています。
今回作ったソースコードはこちらにアップしておきました。