It seems to be getting a lot of attention judging by the likes. But in order to substantively talk about the possibility of a backport, we need to come up with a specific idea for implementing this for SwiftUI. I would like to discuss the practical side of the issue, how it would be possible to add the ability to perform body
with tracking to old versions of SwiftUI.
I've been thinking about this for a couple of days but haven't been able to find a solution with the current capabilities of the language. The best I could find is that ViewBuilder
is not part of the SwiftUI ABI. It is completely covered by @_alwaysEmitIntoClient
attributes. Thus it would be possible to change all of its build*
functions to work with closures. And add a buildFinalResult
function that would wrap everything in a special View
that performs this closure inside a withObservationTracking
call, and the onChange
event would invalidate this View
through a special DynamicProperty
.
Unfortunately, this approach does not fully work. In particular, language statements such as if CONDITION { ... }
, for ... in SEQUENCE
and let ... = EXPRESSION
are outside the responsibility of resultBuilder. In other words, CONDITION
, SEQUENCE
and EXPRESSION
will be evaluated outside of withObservationTracking
. Which makes this solution incomplete.
However, it seems to me not too laborious to add to the compiler a new kind of transformation to the result builders that takes the body of the function to which it is applied as a closure. Something like
func buildByWrapping(_ body: () -> FinalResult) -> ReturnType
It seems that this will not break the general concept of result builders and at the same time will significantly expand their capabilities. In particular, this will allow the SwiftUI team to extend their ViewBuilder
similar to the way I described above.
Thoughts are welcome