2
Help us understand the problem. What are the problem?

TCAでCore Locationを扱うComposable Core Locationのススメ

TCAでCore Locationを扱うComposable Core Locationのススメ

まえがき

The Composable Architecture(以下よりTCA)でCore Logationを使う機会があり、
Point Free製のComposable Core Locationが非常に便利でしたので
https://github.com/pointfreeco/composable-core-location#basic-usage
備忘録として記録しておきます。

どういうものか?

Viewからのユーザーの入力であったり、APIからのレスポンスやロジックなど、
Reducerが開発者が定義したActionをもとに、Stateを更新するという流れだと思いますが、

Core Loacationから緯度経度を取得する場合、
位置情報や位置情報の利用確認の結果、権限がどうなっているかなど、
Core Location側のDelegate関数から、
どのようにTCAのActionとして貰うかが不明でした!

が、このComposable Core Locationを使えば解決できます。

使い方

Composable ArchitectureでCore Locationを
https://github.com/pointfreeco/composable-core-location#basic-usage

EnvironmentにlocationMangerを定義し

struct AppEnvironment {
    public var locationManager: LocationManager
}

EnvironmentにあるComposable Core LogationのLocationManagerに処理をDelegateする。
以下では
Reducer内でonAppearしたたときにLocationMangerにdelegateし、
locationManagerを通じて、位置情報の利用確認の許可を求めています。

static var reducer = Reducer <AppState, AppAction, AppEnvironment> { state, action, environment in
    struct LocationManagerId: Hashable {}
    switch action {
    case .onAppear:
        return .merge(environment.locationManager.delegate()
                        .map(Action.locationManager)
                        .cancellable(id: LocationManagerId()),
                      environment.locationManager
                        .requestWhenInUseAuthorization()
                        .fireAndForget())
    // 省略
    }
}
enum AppAction {
    case onAppear
    case locationManager(LocationManager.Action)
}

このLocationManager.ActionにCoreLocationのDelegate MethodがActionとして定義されています。

   case didChangeAuthorization(CLAuthorizationStatus)
    case didDetermineState(CLRegionState, region: Region)
    case didEnterRegion(Region)
    case didExitRegion(Region)
    case didFailRanging(beaconConstraint: CLBeaconIdentityConstraint, error: Error)
    case didFailWithError(Error)
    case didFinishDeferredUpdatesWithError(Error?)
    case didPauseLocationUpdates
    case didResumeLocationUpdates
    case didStartMonitoring(region: Region)
    case didUpdateHeading(newHeading: Heading)
    case didUpdateLocations([Location])
    case didUpdateTo(newLocation: Location, oldLocation: Location)
    case didVisit(Visit)
    case monitoringDidFail(region: Region?, error: Error)
    case didRangeBeacons([Beacon], satisfyingConstraint: CLBeaconIdentityConstraint)

サンプルコードもありますので
是非是非、Composable Core Location使ってみてください。
https://github.com/pointfreeco/composable-core-location

あとがき

Delegate使うパターンで、自作しないといけないシーンも出てきそうなので、
内部の実装もみていきたい。。。
SwiftUI x TCA x Firestoreでのお仕事募集中です〜!

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
2
Help us understand the problem. What are the problem?