krzysztofzablocki / Inject

Hot Reloading for Swift applications!
MIT License
2.1k stars 114 forks source link

Only add on root view (SwiftUI) #76

Closed Tulleb closed 1 year ago

Tulleb commented 1 year ago

Would it be possible to only add the prerequisites (.enableInjection() & @ObserveInjection var inject) on our root view so it is automatically working for all subviews hierarchy?

Here it is working but I have to reinitiate the view (dismiss / reinit) it for my changes to display.

Amazing lib btw 👏👏👏

johnno1962 commented 1 year ago

Hi, I wish it were possible but it's not due to technical details of how SwiftUI and opaque (some View) types work.

You need to erase the type at every level you want to be able to inject using .enableInjection() or it is possible there is a disagreement on the memory layout of the concrete return type of a body property between injected an un-injected code.

Adding an observer at each level is necessary as SwiftU caches a representation of the current UI at each level. Without the observer you can't guarantee a View will redraw when you inject it even if its superview is marked as having changed.

If you are using the app, there is an option "Prepare Project" on the menu bar that goes through all sources of your app and tries to make these changes automatically though YMMV.

Tulleb commented 1 year ago

Thank you for the details.

Which app are you referring to? If you're talking about InjectionIII.app, I don't see any menu bar when opening it (nothing it happening).

johnno1962 commented 1 year ago

Yes, the InjectionIII.app. When you run it there should be a little blue syringe on the menu bar at the top right of your screen. Open your project using the menu item that pops down, then select "Prepare Project". The code is a little old and doesn't use the new @ObserveInjection property wrapper yet but you should be able to fix it up with a global replace.