2

I am working on SwiftUI and displaying MapView using UIViewRepresentable. Now, when map is loaded then I am calculating route between two points and i am storing that route in model.

class MapInfo: ObservableObject {
    @Published var routeArray: [RouteArray] = []
}

I am calling the calculateRoute() function in UIViewRepresentable MapCoordinator

struct MapView: UIViewRepresentable {
  @StateObject var mapInfo = MapInfo()
}

func requestRoute() {
    // when response is received 
    parentView.mapView.mapInfo.routeArray = responseArray
}

But My problem is SwiftUI View onReceive is not getting called when MapInfo @Published RouteArray is updated.

I have added my code.

struct MapContainerView: View {
      @ObservedObject var mapInfoObj = MapInfo()
      
      var body: some View {
          ZStack {
             MapView()
          }.onReceive(mapInfoObj.$routeArray) { updatedRouteArray in
             print(updatedRouteArray)
          }
      }

}

Any help with this is highly appreciated. Thank you :)

2
  • 1
    You have two different MapInfo instances. You need to pass the one from your MapContainerView to your MapView via its initialiser. Commented Aug 11, 2021 at 10:36
  • yes, you are right @Paulw11. My bad!! I missed this basic thing. Thank you :) Commented Aug 11, 2021 at 12:57

2 Answers 2

2

As @Paulw11 mentioned in the comments, you are using different instances of MapInfo which simply means, updating one instance does not update the other one since they are different.

To solve this, your need to create only one instance of your MapInfo in your MapContainerView and then pass it to your MapContainerView view so both views can share the same data and get updated when the data changes.

Your code would look like:

1. MapView

struct MapView: UIViewRepresentable {
  @ObservedObject var mapInfo: MapInfo
}

func requestRoute() {
    // when response is received 
    parentView.mapView.mapInfo.routeArray = responseArray
}

2. MapContainerView

struct MapContainerView: View {
      @StateObject var mapInfoObj = MapInfo()
      
      var body: some View {
          ZStack {
             // Here now, the two views are sharing the same data
             MapView(mapInfo: mapInfoObj)
          }.onReceive(mapInfoObj.$routeArray) { updatedRouteArray in
             print(updatedRouteArray)
          }
      }

}
Sign up to request clarification or add additional context in comments.

2 Comments

yes, you are right @cedricbahirwe. My bad!! I missed this basic thing. Thank you :)
The pleasure is all mine
0

As mentioned above, I missed to share the variable across different view.

struct MapContainerView: View {
  @StateObject var mapInfoObj = MapInfo()
  
  var body: some View {
      ZStack {
         // Here now, the two views are sharing the same data
         MapView(mapInfo: mapInfoObj)
      }.onReceive(mapInfoObj.$routeArray) { updatedRouteArray in
         print(updatedRouteArray)
      }
   }
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.