iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
Mobile Development

Kotlin 全面啟動 系列 第 7

[Kotlin 全面啟動] 專案結構

  • 分享至 

  • xImage
  •  

昨天我們完成了第一個 KMM 的 Hello world ,今天就來看看這個專案裡長什麼樣子吧!
把專案展開你會發現一個熟悉的結構(如果你熟悉 Android 開發的話)如下:
https://ithelp.ithome.com.tw/upload/images/20220921/20120419JcIHkIuw0f.png
是的,KMM 專案跟 Android 專案的結構大致上是一樣的,他也是使用 gradle 的 build system,這對 Android 工程師來說是一大福音,也讓現有的 Android 專案可以很快的 migrate 成 KMM 的模樣,除了一些設定檔以外,主要的資料夾就是 androidApp、iosApp、shared 這三個囉,讓我們一個一個打開來看看!

build.gradle.kts 是什麼呢?跟 build.gradle 差別是什麼?這邊我們先賣個關子明天再來討論。

androidApp

把 androidApp 展開你會得到以下的結構:

jintinlin@Jintins-Air androidApp % tree -L 3
.
├── build
│   └── ...
├── build.gradle.kts
└── src
    └── main
        ├── AndroidManifest.xml
        ├── java
        └── res

tree 也是個很棒的工具,人如其名是用來讓我們快速了解資料夾結構的工具,在 mac 上也可以直接透過 brew 安裝。

androidApp 沒什麼好說的,跟一般的 android 專案幾乎一模一樣,這一層完全就是個普通 android 專案,跟 shared 的連結也是一樣透過 dependency 的宣告,如下:

dependencies{
  implementation(project(":shared"))
  ...
}

在這禮拜 9/18 的 Kotlin weekly 上,JetBrains 宣布了新版 KMM 的 plugin 將會直接使用 compose 來建立 hello world project 囉,持續更新的感覺真的是感覺很棒呢!

iosApp

這一層其實也跟一般的 iOS app 幾乎一樣,但依據專案建立設定的不同,會分別有 cocoapods 的版本或是 Framework 二種,以下我們分別討論:

Framework

如果你選擇的是是 framework 的方式你會發現在 Build Settings 裡,KMM 已經幫我們把 shared 的 build 連結好了,如下:

https://ithelp.ithome.com.tw/upload/images/20220921/20120419NPzHh8vc1D.png

Cocoapods

如果是 Cocoapods 的版本,可以打開 Podfile 這個檔案,可以發現跟 shared 的連結如下:

target 'iosApp' do
  use_frameworks!
  platform :ios, '14.1'
  pod 'shared', :path => '../shared'
end

shared

這麼說起來,重頭戲應該在這個資料夾裡囉,一樣讓我們用 tree 來檢視看看:

jintinlin@Jintins-Air shared % tree -L 3
.
├── build
│   └── ...
├── build.gradle.kts
├── shared.podspec
└── src
    ├── androidMain
    │   ├── AndroidManifest.xml
    │   └── kotlin
    │       └── com.jintin.myapplication ...
    ├── androidTest
    │   └── kotlin
    │       └── com.jintin.myapplication ...
    ├── commonMain
    │   └── kotlin
    │       └── com.jintin.myapplication ...
    ├── commonTest
    │   └── kotlin
    │       └── com.jintin.myapplication ...
    ├── iosMain
    │   └── kotlin
    │       └── com.jintin.myapplication ...
    └── iosTest
        └── kotlin
            └── com.jintin.myapplication ...

可以發現主要程式碼在 src 裡分三群 androidMain、iosMain、commonMain,而因為我們一開始有選擇加入測試的關係,也自動幫我們加了相對應的測試資料夾。

只是這幾個資料夾是怎麼跟我們的專案連動的呢?有關設定的當然就是要打開 build.gradle.kts 看看囉,最重要的區塊如下:

kotlin {
    android()
    
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach {
        it.binaries.framework {
            baseName = "shared"
        }
    }

    sourceSets {
        val commonMain by getting
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
        val androidMain by getting
        val androidTest by getting
        val iosX64Main by getting
        val iosArm64Main by getting
        val iosSimulatorArm64Main by getting
        val iosMain by creating {
            dependsOn(commonMain)
            iosX64Main.dependsOn(this)
            iosArm64Main.dependsOn(this)
            iosSimulatorArm64Main.dependsOn(this)
        }
        val iosX64Test by getting
        val iosArm64Test by getting
        val iosSimulatorArm64Test by getting
        val iosTest by creating {
            dependsOn(commonTest)
            iosX64Test.dependsOn(this)
            iosArm64Test.dependsOn(this)
            iosSimulatorArm64Test.dependsOn(this)
        }
    }
}

可以藉由 template 建立的檔案看出 KMM 設計的一些端倪,commonMain、androidMain 等變數就是 KMM 連結資料夾的方式,這些 block 裡宣告 dependency 的方式還是跟以前一樣,只是現在必須寫在個別的變數上,另外還有 dependsOn 這個關鍵字幫我們連結每一個 module 之間的關係,我們以 iosTest 為例說明,iosTest 依賴於 commonTest,但執行 iosX64Test、iosArm64Test、iosSimulatorArm64Test 時,就會依賴於 iosTest 囉。

Untitled

大家也可以試著把 commonMain 等名字換一下看哪裡會壞掉,這樣就可以更清楚知道 KMM 是怎麼連結這些程式碼的了。

大概搞懂 KMM 的專案結構後,還記得我們明天要繼續介紹 build.gradle.kts 嗎?不見不散喔~


上一篇
[Kotlin 全面啟動] HelloWorld
下一篇
[Kotlin 全面啟動] build.gradle.kts
系列文
Kotlin 全面啟動 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言