Also, is there anything wrong with the generic Cus...
# compose-android
d
Also, is there anything wrong with the generic CustomNavArg implementation I made (in the thread)? I seem to be getting destinations not found for all those screens... no it seems like I'm getting destination not found for when I use a custom type that's a sealed interface... (using Json polymorphic serializer) for some reason whether I declare all the sub-types and the parent type in the typeMap or not, it just doesn't seem to be finding the route when I try to navigate to it.
solved 1
Copy code
@OptIn(InternalSerializationApi::class)
inline fun <reified T : Any> createNavType(
    noinline serializeAsString: (T) -> String = { it.toString() }
) =
    typeOf<T>() to JsonNavType(T::class.serializer(), serializeAsString)

@OptIn(InternalSerializationApi::class)
inline fun <reified T : Any> createNavTypeForSealed(
    inheritingTypes: List<KType>
): List<Pair<KType, JsonNavType<T>>> {
    val navType = JsonNavType(T::class.serializer())
    return inheritingTypes.map { it to navType }
}

@OptIn(InternalSerializationApi::class)
inline fun <reified T : Any> createListNavType() =
    typeOf<List<T>>() to JsonNavType(ListSerializer(T::class.serializer()))

class JsonNavType<T>(
    private val serializer: KSerializer<T>,
    private val serializeAsString: (T) -> String = { it.toString() }
) : NavType<T>(isNullableAllowed = false) {

    override fun get(bundle: Bundle, key: String): T? {
        return bundle.getString(key)?.let { Json.decodeFromString(serializer, it) }
    }

    override fun parseValue(value: String): T {
        return Json.decodeFromString(serializer, value)
    }

    override fun put(bundle: Bundle, key: String, value: T) {
        bundle.putString(key, Json.encodeToString(serializer, value))
    }

    override fun serializeAsValue(value: T): String {
        return serializeAsString(value)
    }

    @OptIn(ExperimentalSerializationApi::class)
    override val name: String = serializer.descriptor.serialName
}
The problem was I needed to call Uri.encode in serializeAsValue... 😵‍💫
i
Yep, the docs do explicitly mention that, but it is easy to miss: https://developer.android.com/guide/navigation/design/kotlin-dsl#custom-types
d
It took me hours until I finally found that that was the problem... even the function names to be implemented don't really indicate how they will be used in the Nav component... in the end I found it in the NavType KDocs...