Is there any update on bringing SafeArgs to Naviga...
# compose
c
Is there any update on bringing SafeArgs to Navigation Compose? Would love to have type safety for arguments when navigating to a composable
j
I would prefer inline/value class support
i
Given that you build your destinations at runtime (potentially using if statements, for loops, extension methods, sealed classes, etc.), what kind of compile time code generation would you want in the ideal world?
c
@Ian Lake Good question. Seeing as most apps using Navigation Compose that I've seen already model their destinations as objects (to add some strong typing and avoid using magic strings for routes), I think it would make sense for the library to provide an interface or abstract class representing a destination (let's call it
ComposableDestination
), with properties that we can override like
route: String
,
arguments: List<NamedNavArgument>
, and
deepLinks: List<NavDeepLink>
. Then at compile time any `object`s inheriting from it (which could be identified with an annotation if necessary) will get the following generated code: a data class representing a set of arguments that can be passed into this destination (if it takes any), a function that returns an instance of this data class from a
NavBackStackEntry
, and a function for navigating to the destination, which takes in the proper arguments, strongly typed, and under the hood uses them to construct a String representing the route to navigate to. Also, if we have this
ComposableDestination
type, then we could add the following overload for `NavGraphBuilder.composable`:
Copy code
fun NavGraphBuilder.composable(destination: ComposableDestination, content: @Composable (NavBackStackEntry) -> Unit) {
    composable(destination.route, destination.arguments, destination.deepLinks, content)
}
Putting it all together, we can define the destinations and construct the nav graph like so ^
If we want to extend this to also support navigating to a certain nav graph as opposed to a composable, then in addition to
ComposableDestination
there could also be a
NavGraphDestination
type, with the properties
route: String
and
startDestination: String
, along with corresponding overloads for
NavGraphBuilder.navigation
and the
NavHost
composable to take in a
NavGraphDestination
instead of a
route
and
startDestination
directly. Then we can generate a function for navigating to this nav graph, which uses the
route
property under the hood.
i
Okay, so what is stopping you from doing that yourself?
c
I don't have experience writing compiler plugins or code generation. I'm considering learning, so that I can make this happen, but if there was official tooling supported by Google, then it would remove the need for every developer who wants type safety to roll their own. Just like with the original SafeArgs plugin, I don't think every developer/team would want to (or have the resources to) write their own version of SafeArgs, if Google never released it.
Also, given that Navigation Compose is in alpha and its API could change significantly, Google is probably better positioned to create this tooling in a way that won't be rendered obsolete after future Navigation Compose releases than a third party would be.
@Ian Lake So is it safe to say that the answer to my original question is that there are no plans to bring SafeArgs (or something like it) to Navigation Compose? I was just wondering if there was an update on this comment from last year. I am a bit confused if there are no longer any future plans to make this happen, because the official docs say:
Safe Args is strongly recommended for navigating and passing data, because it ensures type-safety.
What is it about the Compose paradigm that makes type-safety no longer as important, if it was previously strongly recommended?
i
That comment is still the latest: everything we've written tooling wise is solely based on parsing static XML that is available at build time. There is no static XML in Compose, so still none of that applies
Since you define your code, you can make it as safe your specific needs allow, which is why we're totally focused on making reliable, lower level APIs that your code can call through to in whatever structure it wants
👍 1
That being said, I'd still love to do more in this space
K 1
I think you should expect the priority to continue to be on the 'you are completely blocked on our team providing basic functional building blocks that work' type of issues. Building higher level constructs on top of those building blocks is what we want to enable for both our team in the future and for you, who may have different priorities shorter term
👍 1
c
Makes sense, thanks for the explanation! Would this be the kind of thing that would be worth tracking an issue for so people can star it if they'd also find it useful, to help inform priorities once the time comes to start building those higher level constructs?
i