Reputation: 33
I have an EnvironmentObject variable that is being used various places.
I would like to update it using a button with a .alert modifier.
The .alert invokes a func within which the EnvironmentObject updates itself with a name supplied by the .alert modifier.
Puzzle is that within the func the EnvironmentObject seems unchanged. On the first use, it shows the initialized values. But when it is used by the Map($...) it does seem to have been updated. Subsequent uses of the button show that the values within the func are always from the last update.
I want to use the EnvironmentObject elsewhere, but it is always one step behind.
here is the code with some comments. If there's another way, please suggest.
import SwiftUI
import MapKit
struct LocationFinderViewCopy: View {
@EnvironmentObject var mapAPI: MapAPI // I am using this elsehwere
@State private var showingAlert = false
@State private var locationName = ""
var body: some View {
VStack {
Map(position: $mapAPI.locations[0].cameraPosition) { //$mapAPI shows the most recent update, despite what I see in the findlocation function
let temp = mapAPI.locations[0].coordinate
let tempCam = mapAPI.locations[0].cameraPosition.region
Annotation(mapAPI.locations[0].name, coordinate: mapAPI.locations[0].coordinate, anchor: .center) {
MapMarkerView()
}
}
Button("Alert find Button") {
showingAlert.toggle()
}
.alert("Location for find", isPresented: $showingAlert) {
TextField("location", text: $locationName)
Button("Cancel", action: doNothing)
Button("OK", action: findLocation)
} message: {
Label("name", systemImage: "circle.circle")
}
}
}
func doNothing() {
}
func findLocation() {
let tempCoord1 = mapAPI.locations[0].coordinate // mapAPI original intiation
let tempCam1 = mapAPI.locations[0].cameraPosition //checking value
let name = locationName
mapAPI.getLocation(address: locationName, delta: 10)
let tempCoord2 = mapAPI.locations[0].coordinate // expected mapAPI to reflect it is still showing init values. Each subsequent entry shows the previous request. same value as tempCoord1
let tempCam2 = mapAPI.locations[0].cameraPosition
}
}
#Preview {
LocationFinderViewCopy()
}
Trying to update an EnvironmentObject and the updates appear out of sync
Upvotes: 1
Views: 98
Reputation: 30746
It's best to use @Environment for your API and have a function that returns a location you can store in a state, e.g.
@Environment(\.mapAPI) var mapAPI
@State var location: Location
@State var gettingLocation = false
Button(gettingLocation ? "Cancel" : "Get Location") {
gettingLocation.toggle()
}
.task(id: gettingLocation) {
if !gettingLocation { return }
location = await mapAPI.getLocation()
gettingLocation = false
}
This way you can avoid the inconsistency issue typical of objects.
Upvotes: 0