Skip to content

프로젝트 수정하기

이 튜토리얼은 IntelliJ IDEA를 사용하지만, Android Studio에서도 동일하게 따라 할 수 있습니다. 두 IDE는 동일한 핵심 기능과 Kotlin Multiplatform 지원을 공유합니다.


이 문서는 공통 로직과 UI를 갖춘 Compose Multiplatform 앱 만들기 튜토리얼의 세 번째 부분입니다. 계속 진행하기 전에 이전 단계를 완료했는지 확인하세요.

First step

Compose Multiplatform 앱 만들기
이 튜토리얼은 IntelliJ IDEA를 사용하지만, Android Studio에서도 따라 할 수 있습니다. 두 IDE는 동일한 핵심 기능과 Kotlin Multiplatform 지원을 공유합니다. 이 문서는 공통 로직과 UI를 갖춘 Compose Multiplatform 앱 만들기 튜토리얼의 첫 번째 부분입니다. Compose Multiplatform 앱 만들기, Composable 코드 살펴보기, 프로젝트 수정하기, 나만의 애플리케이션 만들기를 다룹니다.

Second step
Composable 코드 살펴보기
이 튜토리얼은 IntelliJ IDEA를 사용하지만, Android Studio에서도 따라 할 수 있습니다. 두 IDE는 동일한 핵심 기능과 Kotlin Multiplatform 지원을 공유합니다. 이 문서는 공통 로직과 UI를 갖춘 Compose Multiplatform 앱 만들기 튜토리얼의 두 번째 부분입니다. 계속 진행하기 전에 이전 단계를 완료했는지 확인하세요. Compose Multiplatform 앱 만들기, Composable 코드 살펴보기, 프로젝트 수정하기, 나만의 애플리케이션 만들기를 다룹니다.

Third step 프로젝트 수정하기
Fourth step 나만의 애플리케이션 만들기

Kotlin Multiplatform 마법사로 생성된 코드를 수정하여 App composable 내에 현재 날짜를 표시해 보겠습니다. 이를 위해 프로젝트에 새로운 의존성을 추가하고, UI를 개선하고, 각 플랫폼에서 애플리케이션을 다시 실행합니다.

새로운 의존성 추가하기

플랫폼별 라이브러리와 expect/actual 선언을 사용하여 날짜를 가져올 수도 있습니다. 하지만 Kotlin Multiplatform 라이브러리를 사용할 수 없는 경우에만 이 방식을 사용하는 것을 권장합니다. 이 예제에서는 kotlinx-datetime 라이브러리를 사용할 수 있습니다.

JetBrains에서 제공하는 멀티플랫폼 라이브러리 검색 서비스인 klibs.io에서 타겟 플랫폼에 사용할 수 있는 Kotlin Multiplatform 라이브러리를 찾아볼 수 있습니다.

kotlinx-datetime 라이브러리를 사용하려면 다음 단계를 따르세요:

  1. gradle/libs.versions.toml 파일을 열고 버전 카탈로그에 kotlinx-datetime 의존성을 추가합니다:

    toml
    [versions]
    kotlinx-datetime = "0.8.0"
    
    [libraries]
    kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" }
  2. shared/build.gradle.kts 파일을 열고 공통 코드 소스 세트(common code source set)를 설정하는 섹션에 해당 라이브러리 항목에 대한 참조를 추가합니다:

    kotlin
    kotlin {
        // ...
        sourceSets {
            // ...
            commonMain.dependencies {
                // ...
                implementation(libs.kotlinx.datetime)
            }
        }
    }
  3. 웹 타겟의 경우, 시간대(timezone) 지원을 위해 js-joda 라이브러리가 필요합니다. webApp/build.gradle.kts 파일에 js-joda npm 패키지에 대한 참조를 추가합니다:

    kotlin
    kotlin {
        // ...
        sourceSets {
            // ...
            commonMain.dependencies {
                // ...
                implementation(npm("@js-joda/timezone", "2.25.1"))
            }
        }
    }

    webMain 소스 세트에 의존성을 추가하면 wasmJsjs 타겟 모두에서 라이브러리를 사용할 수 있습니다.

  4. 의존성이 추가되면 IDE에서 제안하는 Gradle 설정 동기화를 수락하거나, Shift를 두 번 누르고 Sync Project with Gradle Files 명령을 실행합니다.

  5. Terminal 도구 창에서 다음 명령어를 실행하여 yarn.lock 파일이 최신 의존성 버전으로 업데이트되도록 합니다:

    shell
    ./gradlew kotlinUpgradeYarnLock kotlinWasmUpgradeYarnLock
  6. webApp/src/webMain/kotlin/.../main.kt 파일에서 @JsModule 어노테이션을 사용하여 js-joda npm 패키지를 임포트합니다:

    kotlin
    import androidx.compose.ui.ExperimentalComposeUiApi
    import androidx.compose.ui.window.ComposeViewport
    import kotlin.js.ExperimentalWasmJsInterop
    import kotlin.js.JsModule
    
    @OptIn(ExperimentalWasmJsInterop::class)
    @JsModule("@js-joda/timezone")
    external object JsJodaTimeZoneModule
    
    private val jsJodaTz = JsJodaTimeZoneModule
    
    @OptIn(ExperimentalComposeUiApi::class)
    fun main() {
        ComposeViewport {
            App()
        }
    }

프로젝트를 버전 관리 시스템(version control)에 커밋할 때, kotlin-js-store 디렉토리에 생성된 yarn.lock 파일들을 포함하세요. 이는 프로젝트를 빌드하는 모든 곳에서 동일한 버전의 JavaScript 의존성이 사용되도록 보장하는 데 도움이 됩니다.

사용자 인터페이스 개선하기

  1. shared/src/commonMain/kotlin/App.kt 파일을 열고 App() composable 뒤에 현재 날짜를 포함하는 문자열을 반환하는 다음 함수를 추가합니다:

    kotlin
    fun todaysDate(): String {
        fun LocalDateTime.format() = toString().substringBefore('T')
    
        val now = Clock.System.now()
        val zone = TimeZone.currentSystemDefault()
        return now.toLocalDateTime(zone).format()
    }
  2. IDE에서 제안하는 임포트를 추가합니다.

    kotlinx.datetime아닌 kotlin.time에서 Clock 클래스를 임포트해야 합니다.

  3. 같은 파일에서 App() composable을 수정하여 이 함수를 호출하고 결과를 표시하는 Text() composable을 포함합니다:

    kotlin
    @Composable
    @Preview
    fun App() {
        MaterialTheme {
            var showContent by remember { mutableStateOf(false) }
            val greeting = remember { Greeting().greet() }
            Column(
                modifier = Modifier
                    .safeContentPadding()
                    .fillMaxSize(),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    text = "Today's date is ${todaysDate()}",
                    modifier = Modifier.padding(20.dp),
                    fontSize = 24.sp,
                    textAlign = TextAlign.Center
                )
                Button(onClick = { showContent = !showContent }) {
                    Text("Click me!")
                }
                AnimatedVisibility(showContent) {
                    Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
                        Image(painterResource(Res.drawable.compose_multiplatform), null)
                        Text("Compose: $greeting")
                    }
                }
            }
        }
    }
  4. IDE의 제안에 따라 누락된 의존성을 임포트합니다.

    미해결 참조

애플리케이션 다시 실행하기

이제 Android, iOS, 데스크톱 및 웹에 대해 동일한 실행 구성을 사용하여 애플리케이션을 다시 실행할 수 있습니다:

Android 및 iOS에서의 첫 Compose Multiplatform 앱
데스크톱에서의 첫 Compose Multiplatform 앱
웹에서의 첫 Compose Multiplatform 앱

다음 단계

튜토리얼의 다음 부분에서는 새로운 Compose Multiplatform 개념을 배우고 나만의 애플리케이션을 처음부터 만들어 봅니다.

다음 단계로 진행하기

도움 받기