Type-Safe Navigation을 적용하면서 화면간 인자를 전달하는 것이 간단해졌다.
하지만 복잡한 구조의 인자를 전달하면서 에러가 발생했다.
typeMap received was {}
나가 전달하고자 하는 구조는 아래와 같다.
// RouteFriendProfileEditor
data class RouteFriendProfileEditor(
val friend: Friend,
)
// Friend
data class Friend(
val friendId: String,
val imageUrl: String?,
val relation: Relation,
val name: String,
val contactFrequency: ContactFrequency,
val birthday: String?,
val anniversaryList: List<Anniversary>,
val memo: String?,
val phone: String?,
val lastContactAt: String?, // "2025-07-16"
)
더 내부에 있는 클래스는 생략한다.
왜 오류가 발생할까?
Type-Safe Navigation 내부의 object에 대해 직렬화하는 로직이 없는 것으로 보인다.
++추가 정리 예정
해결 방법은 아래와 같다.
앱 수준의 모듈에 Parcelable 플러그인을 설치한다. (플러그인 없이 수동 구현을 할 수 있다)
plugins {
id("kotlin-parcelize")
}
직렬화 적용 및 커스텀 type 전달을 위한 typeMap을 선언한다.
Friend 내부 커스텀 타입도 직렬화가 필요하다.
@Serializable
@Parcelize
data class RouteFriendProfileEditor(
val friend: Friend,
) : Parcelable {
companion object {
val routeTypeMap =
mapOf<KType, NavType<*>>(
typeOf<Friend>() to FriendType,
)
}
}
Navigation에 전달할 구현체를 가져오는 방법을 선언한다.
internal val FriendType =
object : NavType<Friend>(
isNullableAllowed = false,
) {
override fun put(
bundle: SavedState,
key: String,
value: Friend,
) {
bundle.putParcelable(key, value)
}
override fun get(
bundle: SavedState,
key: String,
): Friend? =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
bundle.getParcelable(key, Friend::class.java)
} else {
@Suppress("DEPRECATION")
bundle.getParcelable(key)
}
override fun parseValue(value: String): Friend = Json.decodeFromString<Friend>(value)
override fun serializeAsValue(value: Friend): String = Json.encodeToString(value)
}
ViewModel에서 savedStateHandle을 통해 Route를 가져온다.
RouteFriendProfileEditor.routeTypeMap 타입맵을 지정해주어야 한다.
// viewModel에서 사용
private val routeFriendProfileEditor: RouteFriendProfileEditor =
savedStateHandle.toRoute<RouteFriendProfileEditor>(RouteFriendProfileEditor.routeTypeMap)
생각지 못한 부분에서 트러블이 발생했다. 급하게 해결하기 위해 틀린 그림 찾기 마냥 해결방법을 찾고 있던 나를 발견했다.
내부 인자를 어떻게 전달하는지 원리를 알았더라면.. 공부해야지
Ref.
https://developer.android.com/guide/navigation/design/kotlin-dsl?hl=ko
https://github.com/easyhooon/NavigationCustomDataClassArgumentExample/issues/1
https://developer.android.com/kotlin/parcelize?hl=ko