2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SwiftUIで位置情報を取得しているコードの解説

Last updated at Posted at 2022-11-15

はじめに

 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

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?