Does the new Swift 5.5 init(projectedValue:) functionality not work with synthesized memberwise initializers?

I understand that. In fact, I’m a refactoring freak, so I’d happily migrate my codebases. However, I don’t know how many SwiftUI developers (some in large codebases) would be willing to do that. To be clear, I’m not 100% against a Swift 6, hard source break. In fact, my stance, when the time comes and Swift 6's around the corner, will be heavily influenced by the effectiveness of the chosen deprecation.

OK, I think I see where you're coming from. My objection, though, is that — albeit poorly documented — this behavior has been leveraged by popular frameworks (see SwiftUI's use of @Binding) and is now widely used. Last time I checked, SwiftUI engineers didn't urge people to create their own inits. Especially beginners will be confused when a 1-year-old tutorial produces warnings.

Whatever type of deprecation we choose, though, we'll want to promote the use of the new init in a source-compatible way — warning-free or not — so I agree with your first 2 points:

1 Like

Yeah, I agree that a situation requiring all SwiftUI engineers who define a view with an @Binding to define a custom init is a non-starter. I was imagining that whatever version of SwiftUI ships with Swift 5.6 (or whatever version includes the deprecation) would update Binding to provide an init(projectedValue:) so that MyView(value: $binding) could be auto-migrated to MyView($value: $binding).

Anyway, the specifics of just how big of a break is acceptable can shake out during discussion of the pitch. I probably shouldn't speculate too much about what level of breakage library authors will find acceptable when they can just tell us themselves. :slight_smile:

It already has: init(projectedValue:). I thought this is what SE-0293 uses to call function with @Binding parameter:

func foo(@Binding arg: Int) { ... }
...

@State private var number = 0
...
foo($arg: $number)
2 Likes

Oh, yep, even better—haven't gotten to play around with the iOS 15 SDK very much yet, thank you for calling that out @young!

This init is available "iOS 13.0+". I wonder that's the use case of this init before SE-0293.

I believe this is because Binding.init(projectedValue:) is tagged as @_alwaysEmitIntoClient, meaning that even though it was introduced with the iOS 15 SDK, it can be back-deployed by clients as early as iOS 13 (when Binding itself was introduced).

2 Likes

Is there anyway to find all the stuff in SwiftUI that has this annotation? The "source" via "Jump to Definition" do not show this.

1 Like

Yeah, I believe that Xcode displays a "sanitized" version of the swiftinterface file. To get the raw interface I opened one of the .swiftinterface files in the folder: path/to/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/SwiftUI.framework/Modules/SwiftUI.swiftmodule.

Not sure if there's an easier way, though.

1 Like

Have there been any decisions made in this area? @Jumhyn @hborla

I don't know about "decisions" (in terms of concrete ways that the language is going to change, once an implementation is ready), but based on the discussion here, @amritpan, @filip-sakel, and myself discussed and prepared a pitch to realize property wrappers as a first-class part of the memberwise init. See here and chime in with your thoughts! :slightly_smiling_face:

5 Likes