Highlight
MapKit は iOS 26 で
PlaceDescriptor、統一されたMKGeocodingRequest/MKReverseGeocodingRequest、自転車経路用のtransportType、そして MapKit JS の Look Around ビューを導入しました。
主要内容
多くの App の地図体験には共通の課題があります。手元には住所の文字列か緯度経度の組しか持っていないのに、Apple Maps のようなリッチな店舗データを取得できない、という問題です。これまでは情報量の乏しいアノテーションを自前で組み立てるか、MKLocalSearch で候補を引いてから絞り込むしかなく、CRM の同期、App Intents 間での値の受け渡し、プロセスをまたいで特定の地点を参照するようなケースでは扱いが煩雑でした。
今年の MapKit には PlaceDescriptor が追加され、新しい GeoToolbox フレームワークに収められています。これは commonName、住所、座標、デバイスの位置情報をひとつの構造化された参照としてまとめ、MKMapItemRequest に渡すと完全な MKMapItem に解決してくれる、という仕組みです。解決された MapItem は Place ID 経由で取得したものと同等で、公式の名称、アイコン、営業時間をそのまま表示でき、Place Card にもそのまま接続できます。
ジオコーディングの入り口も今回統合されました。MKGeocodingRequest(住所 → 座標)と MKReverseGeocodingRequest(座標 → 住所)が、MapKit のコンテキストにおける CLGeocoder の役割を引き継ぎます。経路 API には transportType = .cycling が追加され、自転車経路がはじめてファーストクラスの存在になりました。MapKit JS 側でも Look Around のインタラクティブビューとイベントコールバックが揃い、Web ページに 3D ストリートビューを直接埋め込めるようになっています。
詳細
PlaceDescriptor の最小構成は、representation ひとつと commonName ひとつだけで作れます。
// Creating and resolving a PlaceDescriptor with coordinate PlaceRepresentation
import GeoToolbox
import MapKit
let annaLiviaCoordinates = CLLocationCoordinate2D(
latitude: 53.347673,
longitude: -6.290198
)
let annaLiviaDescriptor = PlaceDescriptor(
representations: [.coordinate(annaLiviaCoordinates)],
commonName: "Anna Livia Fountain"
)
let request = MKMapItemRequest(placeDescriptor: annaLiviaDescriptor)
do {
annaLiviaMapItem = try await request.mapItem
} catch {
print("Error resolving placeDescriptor: \(error)")
}
ポイントは以下のとおりです。
import GeoToolbox:PlaceDescriptorは MapKit 本体には入っておらず、新フレームワークを別途 import する必要があります。representations: [.coordinate(...)]:representations 配列は精度の高い順に並べます。ここでは座標ひとつだけです。commonName:Sydney Opera House のような公に知られた名称を渡します。「ママの家」のようなプライベートな別名は解決の役には立ちません。MKMapItemRequest(placeDescriptor:):Apple Maps のバックエンドに非同期でリクエストを投げ、descriptor をMKMapItemに解決します。try await request.mapItem:失敗時は throw されるため、do/catch でフォールバックを用意しておきます。
元データが座標ではなく住所の場合は、representation を .address に差し替えます(05:56)。
// Creating and resolving a PlaceDescriptor with address PlaceRepresentation
import GeoToolbox
import MapKit
let address = "121-122 James's St, Dublin 8"
let descriptor = PlaceDescriptor(
representations: [.address(address)],
commonName: "Obelisk Fountain"
)
let request = MKMapItemRequest(placeDescriptor: descriptor)
do {
obeliskFountain = try await request.mapItem
} catch {
print("Error resolving placeDescriptor: \(error)")
}
ポイントは以下のとおりです。
.address(address):番地、市区町村、郵便番号までできるだけ完全な住所文字列を渡したほうが、ヒット率が上がります。- representations 配列の順序は重要です。座標が住所から逆算したものなのであれば、address を先頭に置くべきです。
- 解決ロジックは MapKit のバックエンド側で決まるため、呼び出し側は記述(descriptor)を渡すだけで済みます。
App をまたいで地点を受け渡すケース(App Intents など)では、supportingRepresentations に複数のサービスの ID をまとめて入れておけます(06:45)。
// Creating a PlaceDescriptor with identifiers
import GeoToolbox
let annaLiviaCoordinates = CLLocationCoordinate2D(
latitude: 53.347673,
longitude: -6.290198
)
let identifiers = ["com.apple.MapKit" : "ICBB5FD7684CE949"]
let annaLiviaDescriptor = PlaceDescriptor(
representations: [.coordinate(annaLiviaCoordinates)],
commonName: "Anna Livia Fountain",
supportingRepresentations: [.serviceIdentifiers(identifiers)]
)
ポイントは以下のとおりです。
serviceIdentifiersは辞書型です。key には地図サービスの bundle id(com.apple.MapKit)、value にはそのサービス上の place id を入れます。- MapKit の identifier があれば、
MKMapItemRequestはそれを優先的に利用します。解決に失敗した場合は座標や住所の representation にフォールバックします。 - 複数サービスの id を並べて格納できるので、受け取り側は自分が利用している SDK に対応する値を取り出せます。これが
PlaceDescriptorを App Intents のパラメータに使うのに向いている理由です。
自転車経路は、既存の MKDirections.Request に transportType を一行足すだけで取得できます(16:06)。
// Fetch a cycling route
let request = MKDirections.Request()
request.source = MKMapItem.forCurrentLocation()
request.destination = selectedItem
request.transportType = .cycling
let directions = MKDirections(request: request)
do {
let response = try await directions.calculate()
returnedRoutes = response.routes
} catch {
print("Error calculating directions: \(error)")
}
ポイントは以下のとおりです。
transportType = .cycling:今年追加された enum 値です。これまでは walking / automobile / transit のみでした。MKMapItem.forCurrentLocation():source として現在地を使う場合は、座標を組み立てる必要はありません。directions.calculate()は引き続き async / throws のインターフェースです。- 返ってくる
response.routesは、SwiftUI の Map 上でMapPolylineと組み合わせてそのまま描画できます。
逆ジオコーディングは MKReverseGeocodingRequest で CLGeocoder を置き換える形になります(10:45)。
// Reverse geocode with MapKit
import MapKit
let millCreekCoordinates = CLLocation(latitude: 39.042617, longitude: -94.587526)
if let request = MKReverseGeocodingRequest(location: millCreekCoordinates) {
do {
let mapItems = try await request.mapItems
millCreekMapItem = mapItems.first
} catch {
print("Error reverse geocoding location: \(error)")
}
}
ポイントは以下のとおりです。
- イニシャライザは optional を返します。
if letでアンラップに失敗する場合は、入力の座標が不正だということになります。 request.mapItemsはMKMapItemの配列を直接返してくれるため、CLPlacemarkからMKMapItemへの二段変換が不要です。- 先頭要素が最良一致になることが多いものの、信頼度の判定は業務要件にあわせて行う必要があります。
重要ポイント
-
既存の CRM や Excel の住所データを
PlaceDescriptorに流し込む:多くの App のバックエンドには名称と住所しかなく、これまで Apple Maps スタイルのアノテーションを地図上に出すことができませんでした。なぜやる価値があるのか:リリースすれば、ユーザーは App 内で公式の営業時間・電話番号・Place Card を見られるようになります。どう始めるか:CLGeocoder.geocodeAddressStringをPlaceDescriptor(representations: [.address(...)], commonName:)+MKMapItemRequestに置き換えるだけで、データインポート全体を一箇所の変更でカバーできます。 -
自転車向け App に
transportType = .cyclingを組み込む:これまでは徒歩経路で代用するか、サードパーティの自転車経路 API をつなぐしかありませんでした。なぜやる価値があるのか:Apple Maps の自転車データは標高、勾配、自転車道の優先度までカバーしていて、ネイティブで完結した体験になります。どう始めるか:既存のMKDirections.Requestのコードにrequest.transportType = .cyclingを一行追加し、まず経路品質を検証してから、ユーザーにモード切り替えとして公開するかを判断します。 -
App Intents の入力に
PlaceDescriptorを使う:App をまたいでCLLocationを渡すと、店舗名や ID といった意味情報が失われます。なぜやる価値があるのか:Shortcuts や Siri から「近くの X 店」のようなパラメータを、安定して自分の App に渡せるようになります。どう始めるか:既存のIntentParameterの location フィールドをPlaceDescriptorに差し替え、supportingRepresentationsに自社サービスの ID を併せて格納しておきます。 -
MapKit JS で Look Around ビューを埋め込む:Web 側はこれまで 2D 地図しか出せず、ストリートビューはサードパーティに飛ばすしかありませんでした。なぜやる価値があるのか:観光・不動産系のサイトが詳細ページに Apple の 3D ストリートビューを直接表示できるようになり、滞在時間の伸びが期待できます。どう始めるか:
mapkit.PlaceLookupで Place を取得したあと、mapkit.LookAround(container, place, options)を組み立てます。最初はLookAroundPreviewでサムネイルを置き、クリックで本体を展開する構成にすると扱いやすいです。 -
古い
CLGeocoderの呼び出しをMKGeocodingRequest/MKReverseGeocodingRequestにまとめて書き換える:旧 API はCLPlacemarkを返すため、MKMapItemへの変換がもう一段必要になります。なぜやる価値があるのか:変換層がひとつ減り、エラーポイントもひとつ減ります。どう始めるか:コードベース内のCLGeocoder()の呼び出し箇所を grep し、住所 →MKGeocodingRequest、座標 →MKReverseGeocodingRequestで置換します。イニシャライザが optional を返す点に注意してください。
関連 Session
- Go further with MapKit — 同テーマの完全版 session。
PlaceDescriptor、自転車経路、Look Around、統一された地図 URL までを一通りカバーします。 - Get to know App Intents — App Intents フレームワークの基礎。
PlaceDescriptorは地点パラメータの推奨型として位置付けられています。 - What’s new in SwiftUI — SwiftUI の Map ビューと
MapContentBuilderの最新アップデート。 - Develop for Shortcuts and Spotlight with App Intents —
PlaceDescriptorを Intent パラメータとして Shortcuts と Spotlight に公開する方法。
コメント
GitHub Issues · utterances