[Android]TFT API 이용해서 전적 검색 앱 만들기 - 1

우발자·2025년 9월 15일
post-thumbnail

공부 할 겸 TFT API를 이용하여 전적 검색하는 앱을 만들어볼려고 한다.

우선 https://developer.riotgames.com 에 접속하여 로그인을 프로젝트를 등록해야되는데 앱 이름과 앱 설명을 한 뒤 만들면 되는데 어떤 서비스를 할 것 인지 물어본다. 롤, TFT, 룬테라가 있는데 나는 롤만 해봤고 롤체는 안해본 터라 TFT의 풀네임을 모르고 lol에 포함되어있겠지 해서 리그오브레전드를 골랐는데 알고보니 TFT는 Teamfight Tactics의 약자였던 것이다. 난 처음 들어본 이름이라 몰랐었다.. 그래서 등록했던 프로젝트를 삭제 후 TFT를 제대로 골라서 등록했는데 LOL과 다르게 바로 승인을 안해주고 펜딩 상태가 되었다..
그래서 일단 api먼저 사용하기 전에 초기 설정부터 해주자라고 생각해서 우선 앱을 만들기로 했다.


⚙️ 초기 설정

UI - 100% Compose

뭐.. 당연하게 100% Compose를 이용할 생각이다. xml을 굳이 사용할 필요성을 못느꼈기 때문이다.

아키텍쳐 - 앱 아키텍쳐

기존에 클린 아키텍쳐를 공부하고 있었는데, 안드로이드에서 직접 소개한 아키텍쳐가 있는데 그게 앱 아키텍쳐이다. 클린 아키텍쳐와 다르게 도메인레이어가 옵셔널이라는 점이다. 그래서 내가 만들 앱이 그리 크지 않는 점을 고려해 도메인레이어를 빼고 앱 아키텍쳐를 사용해서 구현할 생각이다.

UI 패턴 - MVI

기존에도 MVI를 사용해봤지만 누군가 이미 만든 구조를 그대로 써왔던터라 깊게 이해하고 쓰진 못했던 것 같아서 이번 기회에 내가 직접 구조를 설계하면서 사용해보고 싶어서 MVI를 사용하기로 했었다.

원래 Jetpack Navigation을 주로 사용해봤다. 그래서 이번에 Alpha 단계인
Navigation3 (개발자 문서)을 사용해볼려고 한다.


🧭 Navigation3

내가 만들 앱이 아직 초기 설정 단계라 화면 이동 및 삭제 그리고 초기 구현로직 정도 이다. 자세한 내용은 개발자 문서를 참고하면 된다.

의존성 추가

의존성 추가는 공식문서에 나온대로 모두 적용하면 된다.

androidx.compose.material3.adaptive:adaptive-navigation3

근데 이 의존성을 추가할려면 maven에 추가도 필요해서 추가해주었다.

// settings.gradle.kts
pluginManagement {
    repositories {
        google()
        gradlePluginPortal()
        mavenCentral()
        maven {
            // You can find the maven URL for other artifacts (e.g. KMP, METALAVA) on their
            // build pages.
            url = uri("https://androidx.dev/snapshots/builds/[buildId]/artifacts/repository")
        }
    }
}

dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven {
            url = uri("https://androidx.dev/snapshots/builds/[buildId]/artifacts/repository")
        }
    }
}

buildId는 25.09.15 기준 14101258이 최신이여서 이걸로 적용하였다.

이동 및 뒤로가기

기존 navigation은 backStack을 직접 관리하진 않았다. 그래서 자유롭게 다룬적이 없는 것 같다. 하지만 이번에 Navigation3에서는 backStack을 직접 키로 관리하여 이동 및 뒤로가기를 한다.

1. 우선 스냅샵 형태에 리스트를 만들어야된다.

// Route.kt
sealed interface Route {
    @Serializable
    data object Main : Route

    @Serializable
    data class Second(
        val data: String
    ) : Route
}

// MainActivity.kt#onCreate
// 초기 화면을 Main으로 설정
setContent {
 val backStack = remember { mutableStateListOf<Route>(Route.Main) } 
 ...

우선 시작화면으로 초기값을 설정한 뒤 리스트 형태로 만들어주면 된다.

backStack.add(Route.Second("바보")) // Second 화면으로 이동
backStack.removeLastOrNull // 뒤로가기 

이제 이동 및 뒤로가기는 해당 리스트를 이용하면 된다.

아직 제대로 깊게 사용하진 않았지만 직관적이면서 정말 간단한 것 같다.

2. NavDisplay

기존과 다른점은 NavHost말고 NavDisplay를 구현하면 된다.
NavDisplay 역시 DSL로도 지원을 해준다. 그래서 나는 DSL를 사용하여 구현해봤다.
(DSL 사용 안한 예시코드는 개발자 문서에 있다.)

// TFTLogNavDisplay.kt
@Composable
fun TFTLogNavDisplay(
    modifier: Modifier = Modifier,
    backStack: List<Route>,
    backStackAdd: (Route) -> Unit,
    backStackRemove: () -> Unit
) {
    NavDisplay(
        backStack = backStack,
        onBack = { backStackRemove() },
        entryProvider = entryProvider {
            entry<Route.Main> {
                MainScreen(
                    modifier = modifier,
                    onNavigate = backStackAdd
                )
            }
            entry<Route.Second> { key ->
                SecondScreen(
                    modifier = modifier,
                    data = key.data
                )
            }
        }
    )
}

나는 backStack과 화면 이동을 최상위인 MainActivity에서 관리하게 하였다.
onBack의 프로퍼티는 뒤로가기 트리거 할 때 람다형태로 호출된다.
entryProvider는 backStack을 NavEntry로 변환해준뒤 현재 스택에 맞는 화면을 보여줄 수 있게 해준다. 나머지는 NavHost랑 비슷하다. data가 있는 경우에는 key를 이용하여 값을 가져올 수 있다.


후기

아직 초기 설정 단계라 깊게 써본건 아니지만 매우 직관적이고 또 쉽게 구현 할 수 있었다. 좀 더 활용할 수 있는 방법을 찾아보고 싶다.

profile
어제보다 나은 개발자가 되자

0개의 댓글