As a newbie to the platform, I'm unhappily confused and frustrated about what I see as an unnecessary limitation in swiftui. I've repeatedly read the explanation that says something along the lines that to compare for changes between instances you need to have the "some" type be known... but why? Why can't you just say, "Oh, the type is different than it was.. must be a change... refresh."
If the type is different it's a change, so rebuild. You're detecting the type difference in the compiler and it feels like you could detect it in the runtime instead. What am I missing? Is anyone else asking for this limitation to be lifted? I'm new to the forum and only see topics on how to deal with this, and not "why" to deal with it.
For the benefit of those who will read, I think Avi is referring to "speed of execution", which is not everything. There are also "speed of developer learning" and "speed of "development". There is also the business decision to accept poor performance in an internal app -- as the decision-maker for the particular application that I intend to build for my company's use, I would be super happy for the execution to be slow, if I can develop without frustration, and quickly.
The compiler could give me a warning that execution will be slow, and I could decide later if I want to optimize it. So, I don't see "speed" as a sufficient answer requiring this to be an error instead of a warning.
Either the type is known at compile time, giving room for optimizations, or it isn't. Internally, SwiftUI relies on the compiler being aware of a View's concrete type to ensure a minimum level of performance. I can appreciate that you don't like this decision, but that's the reason for it.
I want to build libraries that return views that are data-specific and whose "types" will only be determinable at runtime. I'm still learning and don't have the code where I ran into the errors. I'm not certain I "need" the flexibility I'm asking for, but ease of development is about a hundred times more important to me than improved performance... so if AnyView works, that will be what I use.
It's not only about speed, to be clear. SwiftUI wants to know not only that a change occurred at all, but as specifically as possible, where those changes occurred. That's good not only for performance, since having more specific knowledge of where changes can occur means less work diffing and then updating the display, but is also key to providing automatic animations that make sense. It is much more reliable to know that only a certain modifier, like opacity, position, or rotation, changed, and interpolate the value of that attribute, than it would be to take two potentially completely different trees and try to make an animation between them.
If you do need the flexibility AnyView provides, and you're not too picky about transitions, by all means use it. If you do end up needing to add polish to your app, though, the design of SwiftUI is intended to let the framework help get a decent result quicker.
If you do need to return different kinds of views depending on the type of data, you can use a switch statement checking for the type of the data being presented:
struct ContentView: View {
@State var someValue: Any = "Hello"
var body: some View {
switch someValue {
case let someString as String:
Text(someString)
case let someInt as Int:
NumberView(number: someInt)
default:
UnknownView()
}
}
}
This is just a simple case using Any as the data type. You would likely have a protocol that all of the types conform to which would be the type of the state variable i.e. any MyProtocol.