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でのお仕事募集中です〜!