Kotlin Multiplatform Mobile がアルファ段階に移行したので、チュートリアルを試す


背景

最近、Kotlin Multiplatform Mobile(KMM)がアルファ段階に移行したようです。

Kotlin Multiplatform Mobile がアルファ段階に移行 – Kotlin Blog | JetBrains

KMM とは、JetBrains が提供するクロスプラットフォーム対応のモバイル開発用 SDK です。
Kotlin のマルチプラットフォーム対応能力を駆使し、モバイルアプリケーションの構築体験を可能な限り楽しく効率的にするように設計されたさまざまなツールや機能を含んでいます。

見ていて面白そうだったので、試しにチュートリアルをやってみました。
※2020 年 10 月時点の情報なので、今後のアップデートにより変わる可能性があります。

開発環境

開発環境は以下の通りです。

  • Android Studio 4.1 RC 3 以降
  • Xcode 11.3 以降
  • Kotlin 1.4.0 以降
  • Java 1.8.0_73 以降
  • macOS Catalina バージョン 10.15.6

環境構築

以下をベースに進めていきます。

Getting started - Help | Kotlin Multiplatform Mobile Docs

Android Studio version 4.1 RC 3 以降をインストール

Android Studio Previewから、4.1 RC 3 か 4.2 CANARY 13 のいずれかをインストールします。
どちらでも大丈夫です。

Kotlin のバージョンを 1.4.0 以降にアップデート

Configure->Pluginsから、Kotlin を 1.4.0 以降にアップデートします。

Kotlin Multiplatform Mobile をインストール

Configure->Pluginsから、Kotlin Multiplatform Mobile をインストールします。

インストール後、Android Studio を再起動します。

はじめてのマルチプラットフォームアプリ作成

以下をベースに進めていきます。

Create your first multiplatform application - Help | Kotlin Multiplatform Mobile Docs

プロジェクト作成

Create New Projectから新規でプロジェクトを作成します。

Select a Project Templateより、KMM Applicationを選択し、Nextをクリックします。

各項目を以下の通り入力します。

項目 名称
Name KMM Application
Package name com.example.kmmapplication
Save location 任意のフォルダ

Configure ActivityではデフォルトのままFinishをクリックします。

ビルド

早速ビルドしてみます。
まずは Android から。

androidAppを選択してから、ビルド対象の端末を設定してビルドします。

すると、以下のように起動します。

次に iOS を試してみます。
iosAppを選択し、Edit Confiugrations...をクリックします。

Execution targetで端末を設定し、ビルドします。

すると、以下のように起動します。

テストコード

各プラットフォームごとにテストコードが用意されており、それぞれ以下のようにファイルを開いて実行できます。

Android のほうは、shared/src/androidTest/kotlin/com.example.kmmapplication.sharedandroidTest.ktにあります。

package com.example.kmmapplication.shared

import org.junit.Assert.assertTrue
import org.junit.Test

class AndroidGreetingTest {

    @Test
    fun testExample() {
        assertTrue("Check Android is mentioned", Greeting().greeting().contains("Android"))
    }
}

iOS のほうは、shared/src/iosTest/kotlin/com.example.kmmapplication.sharediosTest.ktにあります。

package com.example.kmmapplication.shared

import kotlin.test.Test
import kotlin.test.assertTrue

class IosGreetingTest {

    @Test
    fun testExample() {
        assertTrue(Greeting().greeting().contains("iOS"), "Check iOS is mentioned")
    }
}

どちらもGreeting().greeting()が出力する文字列にプラットフォーム名が含まれているかのテストをしています。
shared/src/commonTest/kotlinという共通用のテストフォルダも用意されているようですが、デフォルトでは何も入っていませんでした。

アプリケーションの更新

画面上では「Hello, [プラットフォーム名とバージョン]」という文字列が表示されていました。この文字列を生成しているクラスがshared/src/commonMain/kotlin/com.example.kmmapplication.sharedGreeting.ktにあります。

package com.example.kmmapplication.shared


class Greeting {
    fun greeting(): String {
        return "Hello, ${Platform().platform}!"
    }
}

このディレクトリには、Android と iOS の両方のプラットフォームの共有コードが保存されます。共有コードに変更を加えると、両方のアプリケーションに変更が表示されます。
試しに以下のように変更してみます。

class Greeting {
    fun greeting(): String {
        return "Guess what it is! > ${Platform().platform.reversed()}!"
    }
}

変更後、各プラットフォームでビルドしてみます。
いずれも変更が反映されていることを確認しました。

Android iOS

最後に、Platform クラスについても確認してみます。
commonMain/kotlin/com.example.kmmapplication.sharedPlatform.ktです。

package com.example.kmmapplication.shared

expect class Platform() {
    val platform: String
}

expectキーワードはマルチプラットフォーム専用のインタフェースにて使われるキーワードで、あるプラットフォームのクラスを使いたい場合に使うキーワードです。
androidMainiosMainにもそれぞれPlatform.ktがあります。

Android のほうは、androidMain/kotlin/com.example.kmmapplication.sharedPlatform.ktです。

package com.example.kmmapplication.shared

actual class Platform actual constructor() {
    actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}"
}

iOS のほうは、iosMain/kotlin/com.example.kmmapplication.sharedPlatform.ktです。

package com.example.kmmapplication.shared


import platform.UIKit.UIDevice

actual class Platform actual constructor() {
    actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}

それぞれactualキーワードが使われています。プラットフォームごとに、expectクラスをactualで実装する必要があります。
interfaceとそれをimplementするclassの関係に似ています。

まとめ

Kotlin Multiplatform Mobile(KMM)がアルファ段階に移行したことを受けて、試しにチュートリアルをやってみました。
どうやら共通化するのはロジックのみで、UI は各プラットフォームごとに独自で実装する必要がありそうです。
さらに以下のようなハンズオンも用意されているので、時間があるときにまた試してみます。

Hands-on: Networking and Data storage - Help | Kotlin Multiplatform Mobile Docs

参考 URL