4
1

【SwiftUI】MapContentBuilderを受け取ってねと怒られた

Last updated at Posted at 2024-07-20

開発環境

バージョン
Xcode 15
Swift 5
iOS 17.5
Mac OS Sonoma 14.5

きっかけ

MapKitを使って次のコードを書いたところ、

SampleMapView
import SwiftUI
import MapKit

struct MapRegionView: View {
    @State var region = MKCoordinateRegion (
    center: CLLocationCoordinate2D (
        latitude: 35.6805702,
        longitude: 139.7676359
    ),
    latitudinalMeters: 1000.0,
    longitudinalMeters: 1000.0
    )
    var body: some View {
        Map(coordinateRegion: $region) // ここでwarning発生
            .edgesIgnoringSafeArea(.bottom)
    }
}

#Preview {
    MapRegionView()
}

以下のwarningエラーが発生しました。

error_log
'init(coordinateRegion:interactionModes:showsUserLocation:userTrackingMode:)' was 
deprecated in iOS 17.0: Use Map initializers that take a MapContentBuilder instead.

動くコードではあるのですが、怒られてるのは気になる…
ということで、エラーの内容を調べてみました。

エラー内容

メッセージ内容の翻訳は以下の通りです。

'init(coordinateRegion:interactionModes:showsUserLocation:userTrackingMode:)' は iOS 17.0 で非推奨になりました。代わりに MapContentBuilder を受け取る Mapのinitializerを使用してください。

つまり、当初のMapを生成する時のイニシャライザの記法(coordinateRegionを使用)ではなく、MapContentBuilderというものを受け取るイニシャライザを書いてね、という内容でした。

MapContentBuilderとは

A result builder that creates map content from closures you provide.

引用:Apple公式ドキュメント「MapContentBuilder」

MapContentBuilderとは、Mapを初期化する際に、地図情報などの内容(MapContent)を生成する新しい方法として導入された機能です。
公式ドキュメントによると、MapContentBuilderは直接呼び出されるのではなく、この型を含むいくつかのイニシャライザを呼び出すことで、MapContentBuilderも暗黙的に呼び出されるとのこと。

↓↓MapContentBuilderを暗黙的に受け取っている型の例↓↓

  • Annotation
  • UserAnnotation
  • Marker
  • MapCircle
  • MapPolygon
  • MapPolyline

参考:Apple公式ドキュメント「Map」

修正してみた

要件

  • MapContentBuilderを(暗黙的に)呼び出すコードになっている
  • 画面の中心点から約10㎞圏内の地図が表示されている

修正したコード

import SwiftUI
import MapKit

extension CLLocationCoordinate2D {
    static let parking = CLLocationCoordinate2D(latitude: 35.6805702, longitude: 139.7676359)
}

struct MapTestView: View {
    @State private var position = MapCameraPosition.region(
             MKCoordinateRegion(
                center: .parking,
                span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
            
            )
       )
    
    var body: some View {
        Map(position: $position) {
            Marker("Parking", coordinate: .parking)
        }
    }
}

#Preview {
    MapTestView()
}

変更点

  • Mapの初期化の際に、Makerというメソッドを使うことによって暗黙的にMapContentBuilderを呼び出している
  • 中心点から約10km範囲を表示するために、MapCameraPositionを使用している

プレビュー画面

image.png

いい感じ!

ちなみに

実は先ほどのコードからそうだったのですが、Map初期化の時にcoordinateRegionを指定していたのをやめるだけでもエラーは消えます。

import SwiftUI
import MapKit

struct MapRegionView: View {
    @State var region = MapCameraPosition.region(MKCoordinateRegion (
        center: CLLocationCoordinate2D (
            latitude: 35.6805702,
            longitude: 139.7676359
        ),
        latitudinalMeters: 1000.0,
        longitudinalMeters: 1000.0
    ))
    
    var body: some View {
        Map(position: $region)
            .edgesIgnoringSafeArea(.bottom)
    }
}

#Preview {
MapRegionView()
}

今回はエラーの勧めどおりに、MapContentBuilderを受け取るような初期化にしてみました。
Swift始めたてでまだまだ分からないことが多いので、今回のような調査→修正のプロセスを大事にしていきたいです。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1