はじめに
SwiftUIで位置情報を取得した時に参考にさせていただいたコードを解説することで復習したり、より理解を深めたりしたいと思い、コード解説をしてQiitaに投稿することにしました。
位置情報を取得したいけれどコードを読むのが苦手だなという方などのお役に立てれば幸いです。
参考にさせていただいたサイト
【SwiftUI】CoreLocationの使い方 | 明日から本気出す
1. LocationViewModelのコード
まず、LocationViewModelのコードの解説をします。
import
位置情報の取得にはCoreLocationを使うため、CoreLocationをimportします。
import CoreLocation
権限の状態と位置情報の宣言
次に権限の状態と位置情報の宣言します。
@Publishedがわからなかったので調べると、@Publishedはビューの更新を行っていることがわかりました。
@Published属性を付けたプロパティがSwiftUIの監視対象となり、値が変更されると参照しているビューが再描画されるそうです。
@Published var authorizationStatus: CLAuthorizationStatus
@Published var lastSeenLocation: CLLocation?
初期化
locationManager.desiredAccuracyで位置情報の精度を設定できます。
locationManager.pausesLocationUpdatesAutomaticallyは位置情報の自動更新の一時停止の設定で、一時停止にする場合はtrueにします。
locationManager.startUpdatingLocationで位置情報の更新をスタートできます。
スタート後、delegateに登録した自身のクラスの対応するメソッドにコールバックが発生します。
override init() {
locationManager = CLLocationManager()
authorizationStatus = locationManager.authorizationStatus
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.allowsBackgroundLocationUpdates = true // バックグラウンド実行中も座標取得する場合、trueにする
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.startUpdatingLocation()
}
権限の要求
requestPermissionでは、位置情報をアプリで使用する権限の要求をします。
func requestPermission() {
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization() // バックグラウンド実行中も座標取得する場合はこちら
}
API呼び出しに応じ、自動的に以下のような画面が出てきます。
ここで、一時的に許可やアプリの使用中は許可、許可しないの3つから選ぶことができます。
ユーザーの選択状況などに依存して、表示されるかどうかが変わります。
※許可しないを選択すると二回目以降は表示されません。
権限の更新
権限の状況が更新された場合、コールバック呼び出しを受けることができます。
権限状態によってはAPI呼び出しが失敗するため、現状の権限を保持しておき、判定などに利用します。
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
authorizationStatus = manager.authorizationStatus
}
位置情報の更新
スタートした後、座標情報の更新に応じてこのメソッドが呼び出されます。
ここで座標情報をプロパティに保持することで、画面描画など別の処理に使用できます。
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
lastSeenLocation = locations.first
}
2. ContentViewのコード
次にContentViewのコードの解説をします。
EnvironmentObject
@EnvironmentObjectを使ってlocationViewModelクラスのインスタンスを共有します。
@EnvironmentObjectはObservableObjectプロトコルに準拠したクラスのインスタンスとViewを紐づける仕組みです。
@ObservedObjectと違って子Viewに順番に渡すのではなく、アプリケーション全体からアクセスすることができます。
@EnvironmentObject var locationViewModel = LocationViewModel()
UIの表示
ここで位置情報をアプリに表示させます。
位置情報はDouble型のため、String型に変更してテキストとして表示させています。
Text("経度:" + String(coordinate?.longitude ?? 0))
Text("緯度:" + String(coordinate?.latitude ?? 0))
Text("高度:" + String(locationViewModel.lastSeenLocation?.altitude ?? 0))
Text("速度:" + String(locationViewModel.lastSeenLocation?.speed ?? 0))
緯度・経度
ここでは、coordinateに2次元の座標位置を入れることで、緯度と経度にアクセスしやすいようにしています。
var coordinate: CLLocationCoordinate2D? {
locationViewModel.lastSeenLocation?.coordinate
}
権限要求画面の表示
ここはボタンを設置して、位置情報の権限要求に移動します。
ボタンを押すとrequestPermissionに移動するため、権限を要求する画面が表示されます。
Button(action: {
locationViewModel.requestPermission()
}) {
Text("位置情報の使用を許可する")
}
参考文献
【SwiftUI】CoreLocationの使い方 | 明日から本気出す
coreLocation | Apple Developer Documentation
CLLocationCoordinate2D | Apple Developer Documentation
【SwiftUI】@EnvironmentObjectの使い方
[SwiftUI][Combine] @Published は、Publisher を提供する Property Wrapper