0

I have a SwiftUI view where I display an image, which is taken from MapKit's MKMapSnapshotter, that relies on some information that is derived from a Core Data property (namely, the coordinates and the color of the marker). I want to be able to regenerate the image whenever any of that information changes. I can't figure out how to accomplish this. It's not as simple as using an @ObservedObject for the NSManagedObject that I want to observe, since there attributes that can change aren't visible directly on the SwiftUI view, which is showing just an image.

I tried use an onChange on some of the Core Data attributes but it won't fire (probably because the attributes aren't actually visible on the SwiftUI view). Is there any other solution?

struct CJContactProfileAddressLabelTestView: View {
    
    @ObservedObject var personAddress: PersonAddress
    @ObservedObject private var locationManager: ContactProfileLocationManager // generates an image using MKMapSnapshotter
    
    init(personAddress: PersonAddress) {
        self.personAddress = personAddress
        self.locationManager = ContactProfileLocationManager(personAddress: personAddress)
    }
    
    var body: some View {
        
        VStack {
            
            if let addressString = personAddress.addressStringWithoutCountry() {
                Text("\(addressString)").multilineTextAlignment(.leading)
            }
            
            if let mapImage = locationManager.mapImage {
                
                Image(uiImage: mapImage)
                    .resizable()
                    .cornerRadius(10)
            }
        }
        .task {
            print("CJProfileAddressView: task called")
            await self.locationManager.getMapSnapshot(from: CLLocation(latitude: self.personAddress.latitude as! CLLocationDegrees, longitude: self.personAddress.longitude as! CLLocationDegrees))
        }
    }
}
1
  • 1
    You should be using @StateObject var locationManager.... Also you are not not creating your self.locationManager in init(...) correctly, it should be self._locationManager = StateObject(wrappedValue: ContactProfileLocationManager(personAddress: personAddress)) See this SO post for examples, alternatives and explanations: stackoverflow.com/questions/62635914/… Commented Sep 26, 2024 at 22:51

1 Answer 1

1

Normally the mapImage would be a transient attribute:

https://developer.apple.com/documentation/coredata/modeling_data/configuring_attributes

Also, .task is designed for you to call an async func that returns a result that you set it on an @State or in your case probably set the transient property.

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

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.