SwiftUI @State/@Binding objects not updating in Release configuration
TL;DR: Reflection Metadata Level set to "Off" (potentially a default from older Xcode projects) can cause @State/@Binding
to have issues around getting the variable to update.
After banging my head against the wall for a couple of hours, I managed to luck out on an issue that seemed extremely fucking weird and I had much hate for SwiftUI until I figured out the problem.
I was in the middle of building a release to test update mechanism on Shortcat when I noticed the onboarding screen's Next
button would not appear to do anything.
The root symptom was the step
binding was somehow not being set to .second
, and was stuck in .first
, confirmed by print statements (trusted tool) before and after:
Button(action: {
withAnimation {
print("before: \(step.rawValue)")
step = .second
print("after: \(step.rawValue)")
}
}) {
This resulted in:
before: first
after: first
Which itself is weird as fuck, but what's weirder is it was only happening when being built for Release. For me, if a build setting is causing code to somehow have read-only variables, something is seriously cooked.
I cleaned my build folder, updated Xcode, made a new project and just put the relevant views into a fresh project, set it to Release, and... it worked fine.
What the fuck?
I tried cutting bits of code out that wasn't in the fresh project (dependencies etc) and nothing.
I had to resort to looking at seeing what build options were different between Development and Release, and eventually happened to change the Reflection Metadata Level
option to All
... and it worked!?
A quick search for swift reflection metadata level
, I spotted a link that said "SwiftUI state not updated in older project" and I figured that absolutely must be it.
The question was 1 year and 10 months old (at time of writing). I gave the relevant answer and upvote, and figured I'd write a post about it so hopefully someone using the keywords I used will also discover the answer one day.