Apple の住所(地名)検索 API を比較する(iOS)

テキストから住所(地名)を得たい場合 (たとえば、"嵐山" という入力から "京都府京都市右京区" という結果が欲しい)

その用途に使用できそうな AppleAPI は、以下がある。

これらの違いや使い道を確認したかったので、テキスト入力をしてそれぞれの API の結果を一覧表示するサンプルを作った。


調べて使ってみてわかったこと

CLGeocoder のリクエスト制限

CLGeocoder は短時間に大量リクエストを行うと失敗する。(CLError.Code.network

この動作はドキュメントにも明記されている。

Apps must be conscious of how they use geocoding. Geocoding requests are rate-limited for each app, so making too many requests in a short period of time may cause some of the requests to fail. (When the maximum rate is exceeded, the geocoder returns an error object with the CLError.Code.network error to the associated completion handler.) Here are some rules of thumb for using this class effectively:

ただし、以下の記載があるので、ユーザアクションに紐づいた頻度程度の API 呼び出し自体は考慮されているようだ。

• Send at most one geocoding request for any one user action.

アプリ側で呼び出すタイミングを気を付ければ、あまりエラーになることは無さそうだ。(逆に言えば、ユーザー入力など関係なく、アプリの動作として大量リクエストを送ったりする用途には使えない)

MKLocalSearch

CLGeocoder とは違い、MKLocalSearch はリクエスト制限でエラーにはならない(連続リクエストをしてエラー発生を観測できなかった)

こちらは、現在地と範囲を指定して地図上にある"近場"の Placemark を検索するのが本来の用途のようだ。(LocalSearch なので)

CLGeocoder とはちがい、住所だけではなく、店舗の名前を知りたいならばこちらを使う。

ただし、MapKit の機能なので、地図表示がないアプリで住所検索をしたいために MKLocalSearch だけ使う、というのはレギュレーションに反していないのか、疑問である。

CLGeocoder では複数の結果が得られない?

f:id:daisuke-t-jp:20200822185109p:plain:w300

iOS に入っている Apple の天気アプリではこのように、テキストに対して住所候補が複数あれば、複数表示される。

このような動作を期待して CLGeocoder を使ってみたが、CLGeocoder はレスポンスは配列であるが、結果は常に単一になっていた。

たとえば "中央区" の場合、iOS の天気アプリのように、日本国内にある中央区を複数候補を返して欲しいが、ひとつの中央区しか CLGeocoder は返さない(現在位置から一番近い "中央区" になる?)

この CLGeocoder のレスポンスが一つしか得られない問題は StackoverFlow でも散見されるので、どうにかなる話では無さそうだ。

「候補が複数欲しい」場合は、AppleAPI は使わず他のサービス(GoogleAPI など)を使う必要があるようだ。