본문 바로가기
Android Application/코틀린 멀티플랫폼

안드로이드 스튜디오 + 코틀린 멀티플랫폼(Kotlin Multiplatform) 프로젝트 생성

by sdchjjj 2023. 4. 5.
728x90

안녕하세요.

이번 포스팅에서는 안드로이드 스튜디오를 통해 코틀린 멀티플랫폼 모바일 앱 프로젝트를 생성해 보겠습니다.

 

※ iOS app을 실행해 보고, 소스를 확인하기 위해서는 Xcode도 설치되어 있어야 합니다.

 

가장 먼저 Kotlin Multiplatform Mobile Plugin 설치를 합니다(figure1 참조).

Android Studio -> Preferences(Settings) -> Plugins으로 진입해 설치합니다.

figure1. install plugin

 

설치가 끝나면 새로운 프로젝트를 생성합니다(figure2 참조).

figure2. create new project

 

프로젝트 이름만 적어주고 Next를 선택합니다(figure3 참조).

figure3. fill in project name

 

마지막 페이지에서 iOS fragmework distribution을 Regular fragmework로 선택하고 Finish를 눌러 줍니다(figure4 참조).

figure4. select iOS framework distribution

 

패키지 트리구조를 Project로 바꾸고 열어보면 여러 모듈들이 생성되어 있습니다(figure5 참조).

figure5. modules

 

여기서 아무것도 건드리지 않고 바로 에뮬레이터를 돌려보겠습니다.

 

먼저 androidApp을 선택하고 run을 누릅니다(figure6 참조).

figure6. select androidApp
figure7 run androidApp

잘 실행되었습니다.

 

이번에는 iosApp을 선택하고 실행시켜 보겠습니다(figure8 참조).

figure8. select iosApp
figure9. run isoApp

iosApp도 무사히 실행되었습니다.

 

androidApp은 실행이 잘 되는데 iosApp은 아래와 같은 error와 함께 build fail이 나는 분이 있을 수 있습니다.

> Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.

 

그런 분들은 Android Studio -> Preferences(Settings) -> Build, Execution, Deployment -> Build Tools -> Gradle로 가셔서 Gradle JDK를 11로 설정해 주시면 됩니다. 없다면 다운로드한 뒤 설정해 줍니다(figure10 참조).

figure10. Gradle JDK

 

위 설정을 마쳤음에도 fail이 날 수 있습니다.

그런 분들은 JDK 경로를 확인하여 gradle.properties에 아래와 같이 내용을 직접 세팅해 줍니다.

gradle.properties

#JDK
org.gradle.java.home=/Applications/Android Studio_4.2.app/Contents/jre/Contents/Home

현재 예시에 세팅된 경로는 개인적인 경로이므로, JDK가 있는 자신의 경로를 확인하여 입력해 줍니다(figure10에서 경로 확인 가능).

 

이제 소스 쪽을 간단하게 살펴보겠습니다.

먼저 Android 소스입니다.

 

androidApp > src > main > java > com.contents.... > MainActivity.kt 클래스를 열어봅니다(figure11 확인).

figure11. MainActivity.kt

 

Android는 MainActivity에 jectpack compose로 작성이 되어있습니다.

MainActivity.kt 초기 상태

package com.contents.sampleapp.android

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.contents.sampleapp.Greeting

@Composable
fun MyApplicationTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colors = if (darkTheme) {
        darkColors(
            primary = Color(0xFFBB86FC),
            primaryVariant = Color(0xFF3700B3),
            secondary = Color(0xFF03DAC5)
        )
    } else {
        lightColors(
            primary = Color(0xFF6200EE),
            primaryVariant = Color(0xFF3700B3),
            secondary = Color(0xFF03DAC5)
        )
    }
    val typography = Typography(
        body1 = TextStyle(
            fontFamily = FontFamily.Default,
            fontWeight = FontWeight.Normal,
            fontSize = 16.sp
        )
    )
    val shapes = Shapes(
        small = RoundedCornerShape(4.dp),
        medium = RoundedCornerShape(4.dp),
        large = RoundedCornerShape(0.dp)
    )

    MaterialTheme(
        colors = colors,
        typography = typography,
        shapes = shapes,
        content = content
    )
}

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Greeting(Greeting().greeting())
                }
            }
        }
    }
}

@Composable
fun Greeting(text: String) {
    Text(text = text)
}

@Preview
@Composable
fun DefaultPreview() {
    MyApplicationTheme {
        Greeting("Hello, Android!")
    }
}

 

다음은 ios를 보겠습니다. 

 

iosApp > isoApp.xcodeproj를 오른쪽 클릭하고 Open In > Xcode를 선택합니다(figure12 참조).

figure12. open in Xcode

 

Xcod를 통해 프로젝트가 열립니다.

여기서 ContentView를 열어봅니다(figure13 참조).

figure13. ContentView

 

SwiftUI로 작성이 되어있습니다.

ContentView

import SwiftUI
import shared

struct ContentView: View {
    let greet = Greeting().greeting()

    var body: some View {
        Text(greet)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

 

무사히 프로젝트 생성을 마쳤습니다.

 

이상 포스팅을 마치겠습니다.

 

감사합니다.

728x90

댓글