MKCoordinateRegion Binding warning #1576
-
Hey, there. I am trying to make a mapview using tca. The Map instance requires MKCoordinateRegion to be bindable. Thus, I made the Map.Action to conform to BindableAction and created body Property to implement BindingReducer and Reduce struct like below. struct Map: ReducerProtocol {
struct State: Equatable {
var locationAddress: String
@BindableState var region: MKCoordinateRegion = MKCoordinateRegion()
var placeName: String = ""
var coordinate: CLLocationCoordinate2D?
}
enum Action: BindableAction, Equatable {
case binding(BindingAction<State>)
case onFetchLocation
case locationResponse(TaskResult<Location>)
}
@Dependency(\.meetingDataClient) var dataClient
var body: some ReducerProtocol<State, Action> {
BindingReducer()
Reduce { state, action in
switch action {
case .onFetchLocation:
return .task { [locationAddress = state.locationAddress] in
return await .locationResponse(TaskResult {
try await meetingDataClient.fetchCoordinate(locationAddress)
})
}
case .locationResponse(.failure):
return .none
case .locationResponse(.success(let location)):
let coordinate = location.coordinate
state.meetingRegion = MKCoordinateRegion(
center: coordinate,
span: MKCoordinateSpan(
latitudeDelta: 0.008,
longitudeDelta: 0.008
)
)
state.coordinate = location.coordinate
state.placeName = location.name
return .none
case .binding:
return .none
}
}
}
} Since my region is Bindable, I could use it on my view like below: import ComposableArchitecture
import MapKit
import SwiftUI
struct MeetingMapView: View {
let store: StoreOf<MeetingMap>
var body: some View {
WithViewStore(
store,
observe: { $0 }
) { viewStore in
VStack(alignment: .leading) {
.
.
.
if let validCoordinate = viewStore.coordinate {
Map(
coordinateRegion: viewStore.binding(\.$region),
annotationItems: [validCoordinate]
) {
MapAnnotation(coordinate: $0) {
.
.
.
}
}
}
}
.task { await viewStore.send(.onFetchLocation).finish() }
}
}
} everything seems to work fine. In fact, I could check desired location on my simulator. However, one thing that troubles on my mind is the messages that I see on debugging area:
am I using the Binding Reducer incorrectly? Or perhaps...MKCoordinateRegion may be in appropriate place to implement BindableAction and Binding Reducer. If I use the original binding like below, the message disappears. Hmm..I would like to know what to do with it. Map(coordinateRegion: viewStore.binding(
get: \.region,
send: { _ in .onFetchLocation }
) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Hey @inwoodev! This is a vanilla bug with SwiftUI that is unfortunately present even in Xcode 14.1RC2. For example, the following idiomatic example raises a similar warning. class Model: ObservableObject {
@Published var region = MKCoordinateRegion(
center: .init(),
span: .init(latitudeDelta: 180, longitudeDelta: 180)
)
}
struct ContentView: View {
@StateObject var model = Model()
var body: some View {
Map(coordinateRegion: $model.region)
}
} There was recently a bug with SwiftUI where, in a few situations, some UIKit wrappers were not properly awaiting for In your case, your
There is no real solution that we can implement from our side unfortunately. The best we can do is file a FB with the vanilla reproduction, and hope for a timely fix. We can maybe provide a helper on binding that would hop in extension Binding {
public var fixWarnings: Self {
#if DEBUG
return Self {
self.wrappedValue
} set: { newValue, transation in
DispatchQueue.main.async {
withTransaction(self.transaction) {
self.wrappedValue = newValue
}
}
}
#else
return self
#endif
}
} It seems to work in the vanilla case, but I can't provide any guarantee, and it's only intended to be used for the time being, while the issue isn't fixed on Apple's side. You can probably remove the |
Beta Was this translation helpful? Give feedback.
Hey @inwoodev! This is a vanilla bug with SwiftUI that is unfortunately present even in Xcode 14.1RC2. For example, the following idiomatic example raises a similar warning.
There was recently a bug with SwiftUI where, in a few situations, some UIKit wrappers were not properly awaiting for
body
to finish to publish changes, which triggered the warning when the setter part of the binding was activate…