I wrote a new article about UIViewRepresentable. I came up with two rules for working with them: make all updates from UIKit -> SwiftUI async, and only update what's really needed when setting UIKit properties. If anyone has more feedback I'd love to hear it. https://chris.eidhof.nl/post/view-representable/
@810ec5be nice! Will look at this a bit more closely over the weekend but those rules reflect my own experience. The devil is in the details 😂 I also love how you used a map wrapper as an example. It’s such a great illustration of the problems one often runs into.
@810ec5be @b57999c7 One big caveat with updating from UIKit -> SwiftUI async is that what’s on screen and the SwiftUI state will be desynchronized for a short while, e.g. it could be possible to click a button and execute its action while it is in a 'disabled' SwiftUI state. I don’t know if there is any other way to do this, maybe: only do async in case of the "Modifying state during view update" message?
@810ec5be Thanks for sharing! I played with the NSTextView example a bit. The default behavior is terrible! 😆 I do see how scheduling updates fixes on the main queue fixes the UI update problem. We're using this in similar situations to fire off updates. But my love/hate relationship and intimacy with text views terrifies me of the fact that 1) one user interaction can result in multiple delegate callbacks, and so 2) we space out performing actual updates across 2+ run loop runs.
@810ec5be Do you know any benefits from the pattern 'inject the parent into the coordinator' over just passing the Bindings? I've never seen this before and wonder if I'm missing any pitfalls. See attached picture for the equivalent I know of. https://files.mastodon.social/media_attachments/files/111/057/194/059/897/112/original/54e67b7e7b143d6c.png
@810ec5be I love this article, this is an area I'm learning about right now. My view is you should never write to bindings outside of a SwiftUI view call back. Even synchronizing updates onto the main thread, traditionally, didn't save you from writing at the wrong moment in the view life cycle. It's possible that has changed more recently. I suggest using an observable object to synchronize the changes; these are safe to write to at any time using the main thread.
@810ec5be a solution I’ve used in the past that I’m not sure totally makes sense is to block updates from UIKit -> SwiftUI inside of updateUIView instead of always dispatching async.