Tasuke HubLearn · Solve · Grow
#Kotlin Multiplatform

Kotlin Multiplatform(KMP)実践ガイド:iOS/Androidアプリのコードを共通化する【2025年版】

Kotlin Multiplatform (KMP) を利用して、iOSとAndroidアプリのビジネスロジックを共通化しつつ、UIはSwiftUIとJetpack Composeでネイティブに実装するハイブリッドアプローチを実践的に解説します。

時計のアイコン19 September, 2025
TH

Tasuke Hub管理人

東証プライム市場上場企業エンジニア

情報系修士卒業後、大手IT企業にてフルスタックエンジニアとして活躍。 Webアプリケーション開発からクラウドインフラ構築まで幅広い技術に精通し、 複数のプロジェクトでリードエンジニアを担当。 技術ブログやオープンソースへの貢献を通じて、日本のIT技術コミュニティに積極的に関わっている。

🎓情報系修士🏢東証プライム上場企業💻フルスタックエンジニア📝技術ブログ執筆者

はじめに:Kotlin Multiplatform (KMP) とは? なぜ今注目なのか?

クロスプラットフォーム開発の世界では、これまで「UIまで含めてすべてを共通化する」アプローチ(React Native, Flutterなど)が主流でした。しかし、プラットフォーム固有のユーザー体験を損なうという課題も指摘されてきました。

Kotlin Multiplatform (KMP) は、この問題に対する新しい答えを提示します。KMPは、UIを除くビジネスロジック、データ層、ネットワーク通信といったアプリケーションの頭脳部分をKotlinで一度だけ書き、それをiOSとAndroidの両方で共有する技術です。

KMPの最大の魅力は、以下の2つの世界の「良いとこ取り」ができる点です。

  1. 開発効率の向上: 重要なビジネスロジックを共通化することで、コードの重複をなくし、バグの発生を抑え、開発スピードを向上させます。
  2. ネイティブなUI/UXの実現: UI部分は各プラットフォームの最新技術(AndroidではJetpack Compose、iOSではSwiftUI)を使ってネイティブに実装します。これにより、ユーザーはプラットフォームに最適化された滑らかな操作感を享受できます。

2023年11月にStable版がリリースされ、GoogleやJetBrainsの強力なサポートのもと、KMPは2025年現在、本番環境で採用できる信頼性の高い選択肢となっています。

本記事では、KMPを使って簡単なニュースアプリを開発する手順を通して、その実践的な使い方を学びます。

ベストマッチ

最短で課題解決する一冊

この記事の内容と高い親和性が確認できたベストマッチです。早めにチェックしておきましょう。

KMPのアーキテクチャ:何を共通化し、何をネイティブに残すか

KMPプロジェクトは、一般的に3つの主要なモジュールで構成されます。

  • shared: 共通化するコードを置くモジュール。Kotlinで記述します。
    • commonMain: プラットフォームに依存しない純粋なKotlinコード(ビジネスロジック、データクラスなど)。
    • androidMain: Android固有のAPI(Context, SharedPreferencesなど)にアクセスする必要がある場合のコード。
    • iosMain: iOS固有のAPI(CoreFoundation, UIKitなど)にアクセスする必要がある場合のコード。
  • androidApp: Androidアプリのモジュール。UIはJetpack Composeで実装し、sharedモジュールをライブラリとして利用します。
  • iosApp: iOSアプリのモジュール。UIはSwiftUIで実装し、sharedモジュールをフレームワークとして利用します。

KMP Architecture

このアーキテクチャにより、ロジックの変更はsharedモジュール一箇所だけで済み、両プラットフォームに即座に反映されます。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

開発環境のセットアップ

KMP開発には、Android StudioKotlin Multiplatform Mobileプラグインが必要です。

  1. 最新版のAndroid Studioをインストールします。
  2. 「Preferences/Settings」>「Plugins」から「Kotlin Multiplatform Mobile」を検索し、インストールします。
  3. iOSアプリをビルド・実行するために、Xcodeもインストールしておきます。

準備ができたら、Android Studioの「New Project」から「Kotlin Multiplatform App」を選択し、ウィザードに従ってプロジェクトを作成します。iOS framework distributionは「Regular framework」を選択するのがシンプルで始めやすいでしょう。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

ステップ1:共有モジュール (shared) でAPIクライアントを実装する

sharedモジュールに、プラットフォーム非依存のHTTPクライアントであるKtorと、JSONのシリアライズ/デシリアライズを行うKotlinx Serializationを導入します。

shared/build.gradle.ktsdependenciesブロックに以下を追加します。

// ...
    sourceSets {
        val commonMain by getting {
            dependencies {
                // Ktor for networking
                implementation("io.ktor:ktor-client-core:2.3.11")
                implementation("io.ktor:ktor-client-content-negotiation:2.3.11")
                implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.11")

                // Kotlinx Serialization
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
            }
        }
        val androidMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-okhttp:2.3.11")
            }
        }
        val iosMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-darwin:2.3.11")
            }
        }
    }
// ...

次に、commonMainにAPIから取得する記事データを表すArticle.ktと、実際に通信を行うNewsApi.ktを作成します。

// shared/src/commonMain/kotlin/com/example/myapp/Article.kt
package com.example.myapp

import kotlinx.serialization.Serializable

@Serializable
data class Article(
    val title: String,
    val description: String?,
    val url: String
)

// shared/src/commonMain/kotlin/com/example/myapp/NewsApi.kt
package com.example.myapp

import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.request.get
import io.ktor.serialization.kotlinx.json.json

class NewsApi {
    private val client = HttpClient {
        install(ContentNegotiation) {
            json()
        }
    }

    // suspend関数として定義することで、非同期処理を簡潔に書ける
    suspend fun fetchArticles(): List<Article> {
        // 実際にはここにニュースAPIのURLを入れる
        val response = client.get("https://api.example.com/news")
        return response.body()
    }
}

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

ステップ2:Androidアプリから共有ロジックを呼び出す

androidAppモジュールで、Jetpack Composeを使ってUIを構築し、sharedモジュールのNewsApiを呼び出します。

// androidApp/src/main/java/com/example/myapp/android/MainActivity.kt
package com.example.myapp.android

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Text
import androidx.compose.runtime.*
import com.example.myapp.NewsApi

class MainActivity : ComponentActivity() {
    private val newsApi = NewsApi()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            var articles by remember { mutableStateOf(emptyList<com.example.myapp.Article>()) }

            // Composableのライフサイクルに合わせてコルーチンを起動
            LaunchedEffect(Unit) {
                articles = newsApi.fetchArticles()
            }

            LazyColumn {
                items(articles) { article ->
                    Text(text = article.title)
                }
            }
        }
    }
}

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

ステップ3:iOSアプリから共有ロジックを呼び出す

iOSでは、sharedモジュールがコンパイルされてshared.frameworkという形で提供されます。SwiftUIからこれを呼び出します。

Swiftはsuspend関数を直接呼び出せませんが、KMPはsuspend関数をcompletionHandler付きのコールバック形式に自動変換してくれます。

// iosApp/iosApp/ContentView.swift
import SwiftUI
import shared // sharedフレームワークをインポート

struct ContentView: View {
    @State private var articles: [Article] = []
    private let newsApi = NewsApi()

    var body: some View {
        List(articles, id: \.url) { article in
            Text(article.title)
        }
        .onAppear {
            // APIを呼び出す
            newsApi.fetchArticles { fetchedArticles, error in
                if let fetchedArticles = fetchedArticles {
                    self.articles = fetchedArticles
                }
            }
        }
    }
}

これで、AndroidとiOSの両方で、同じKotlinで書かれたロジックを共有するアプリが完成しました。ロジックの修正はsharedモジュールだけで済みます。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

まとめ:ネイティブの体験と開発効率の両立

Kotlin Multiplatformは、モバイルアプリ開発における「銀の弾丸」ではないかもしれませんが、「開発効率」と「ネイティブなユーザー体験」という、これまでトレードオフの関係にあった2つの要素を高いレベルで両立させる強力な選択肢です。

  • ロジックは一度書けばOK: Kotlinで書いたビジネスロジックは、プラットフォームを意識することなく再利用できます。
  • UIはネイティブで: SwiftUIとJetpack Composeという、各プラットフォームで最もモダンで表現力豊かなUIフレームワークを最大限に活用できます。
  • 既存アプリへの導入も可能: 新規プロジェクトだけでなく、既存のネイティブアプリの一部をKMPで置き換えていく、漸進的な導入も可能です。

もしあなたがネイティブアプリのパフォーマンスやUXに妥協したくない、でも開発効率も上げたい、と考えているなら、Kotlin Multiplatformは試してみる価値のある技術です。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

この記事をシェア

続けて読みたい記事

編集部がピックアップした関連記事で学びを広げましょう。

#Tauri

Tauri v2でスマホアプリ開発!React + RustでiOS/Androidアプリを作る【2025年入門】

2025/11/26
#Platform Engineering

Platform EngineeringはDevOpsを置き換えるか?【2025年版】

2025/9/3
#Astro

Astro 4.0実践ガイド:アイランドアーキテクチャで高速なWebサイトを構築する【2025年版】

2025/9/19
#Android

モダンAndroid開発入門:KotlinとJetpack Composeで作るシンプルなToDoアプリ

2025/9/18
#Swift

SwiftはiOSだけじゃない!サーバーサイドSwift「Vapor」実践ガイド【2025年版】

2025/11/26
#Svelte

Svelte 5 Runes実践ガイド:$stateと$effectで実現する新しいリアクティビティ【2025年版】

2025/9/19