$30 off During Our Annual Pro Sale. View Details »

KMMでマルチプラットフォーム開発を始めよう

akkie76
June 10, 2023

 KMMでマルチプラットフォーム開発を始めよう

akkie76

June 10, 2023
Tweet

More Decks by akkie76

Other Decks in Technology

Transcript

  1. ランチタイムLT会 #1
    ©2023 RAKUS Co., Ltd.
    KMMで始めるマルチプラットフォーム開発
    @akkiee76
    ランチタイムLT会 #1

    View Slide

  2. ランチタイムLT会 #1
    Akihiko Sato / 株式会社ラクス Lead Engineer / @akkiee76
    SaaS 開発 (Backend, Frontend) / Mobile 開発 (iOS, Android)
    上流工程、コードレビュー、チームの課題改善など
    コールドブリューコーヒー☕ / パン作り🍞 / あんバターフランス🥐
    自己紹介

    View Slide

  3. ランチタイムLT会 #1
    会社紹介
    株式会社ラクス
    「ITサービスで企業の成長を継続的に支援します」
    をミッションに、お客様の課題解決やビジネスの成
    長をを継続的に支援するクラウドサービスを提供し
    ています。

    View Slide

  4. ランチタイムLT会 #1
    今日伝えたいこと
    Kotlin Multiplatform for Mobile
    (KMM) 
    を活用したクロスプラットフォーム開発の導入

    View Slide

  5. ランチタイムLT会 #1
    クロスプラットフォーム開発とは?
    1つのコードベースを使用して複数のモバイルプラットフォーム向けに
    アプリを開発する手法。開発者は、異なるプラットフォームごとに独立したア
    プリを作成する必要がなくなり、開発時間とリソースを節約することも。
    ・ React Native
    ・ Flutter
    ・ Unity

    View Slide

  6. ランチタイムLT会 #1
    クロスプラットフォーム開発とは?
    メリット
    ・ 開発 / メンテコストの削減 👑
    デメリット
    ・ ネイティブアプリ固有の機能が実装しにくい
        ・ プラグインが必要だったり・・・
       ・ UIがネイティブに劣る

    View Slide

  7. ランチタイムLT会 #1
    クロスプラットフォーム開発の悩み
    1. 開発速度・コスト重視でクロスプラットフォームを選定
    2. 片手落ち感があっても、ひとまずリリース
    3. ネイティブの機能要求が増えて来る
    4. プラグインだと機能拡張に限界を感じる(EOLを迎えることも)
    5. やっぱりネイティブにしよう

    View Slide

  8. ランチタイムLT会 #1
    Kotlin Multiplatform for Mobile (KMM)
    JetBrainsが開発したKotlinベースのクロスプラットフォーム
    開発フレームワーク。1つの共通のKotlinコードベースを使用して、
    iOSとAndroidの両方のプラットフォーム向けにネイティブアプリを
    開発することができる点が特徴。

    View Slide

  9. ランチタイムLT会 #1
    Kotlin Multiplatform for Mobile (KMM)
    フレームワークイメージ

    View Slide

  10. ランチタイムLT会 #1
    Kotlin Multiplatform for Mobile (KMM)
    アーキテクチャイメージ
    Compose Multiplatform

    View Slide

  11. ランチタイムLT会 #1
    ここからは導入手順を紹介します

    View Slide

  12. ランチタイムLT会 #1
    KMM開発に必要な環境
    ・ macOS
    ・ Android Studio
    ・ Xcode
    ・ JDK
    ・ Kotlin Multiplatform Mobile plugin
    ・ Kotlin plugin
    あとは brew install kdoctor を実行するだけ
    brew install kdoctor

    View Slide

  13. ランチタイムLT会 #1
    Android Studio からプロジェクト作成

    View Slide

  14. ランチタイムLT会 #1
    プロジェクト構成

    View Slide

  15. ランチタイムLT会 #1
    プロジェクトビルド

    View Slide

  16. ランチタイムLT会 #1
    KMMによって出力されたコード(Android)
    class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
    MyApplicationTheme {
    Surface(
    modifier = Modifier.fillMaxSize(),
    color = MaterialTheme.colors.background
    ) {
    GreetingView(Greeting().greet())
    }
    }
    }
    }
    }
    @Composable
    fun GreetingView(text: String) {
    Text(text = text)
    }
    MainActivity.kt

    View Slide

  17. ランチタイムLT会 #1
    KMMによって出力されたコード(iOS)
    ContentView.swift
    import SwiftUI
    import shared
    struct ContentView: View {
    let greet = Greeting().greet()
    var body: some View {
    Text(greet)
    }
    }
    struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
    ContentView()
    }
    }

    View Slide

  18. ランチタイムLT会 #1
    KMMによって出力されたコード(iOS)
    Shared.h
    __attribute__((objc_subclassing_restricted))
    __attribute__((swift_name("Greeting")))
    @interface SharedGreeting : SharedBase
    - (instancetype)init __attribute__((swift_name("init()")))
    __attribute__((objc_designated_initializer));
    + (instancetype)new __attribute__((availability(swift, unavailable, message="use object
    initializers instead")));
    - (NSString *)greet __attribute__((swift_name("greet()")));
    @end

    View Slide

  19. ランチタイムLT会 #1
    KMMによって出力されたコード(shared)
    /commonMain/kotlin
    class Greeting {
    private val platform: Platform = getPlatform()
    fun greet(): String {
    return "Hello, ${platform.name}!"
    }
    }
    interface Platform {
    val name: String
    }
    expect fun getPlatform(): Platform
    class IOSPlatform: Platform {
    override val name: String =
    UIDevice.currentDevice.systemName() + " " +
    UIDevice.currentDevice.systemVersion
    }
    actual fun getPlatform(): Platform = IOSPlatform()
    class AndroidPlatform : Platform {
    override val name: String = "Android
    ${android.os.Build.VERSION.SDK_INT}"
    }
    actual fun getPlatform(): Platform =
    AndroidPlatform()
    /iosMain/kotlin /kotlin

    View Slide

  20. ランチタイムLT会 #1
    個人的な初感
    ・ Jetpack Compose、Swift UI といったモダンフレームワークが採用
    ・ Kotlinで実装する共通ロジックは、柔軟に設計ができる
    ・ Android、iOS 両方のアーキテクチャの知見が必要
    ・ これまでのマルチプラットフォーム開発より難易度高い印象
    ・ 使いこなせたら生産性が爆上がりしそう

    View Slide

  21. ランチタイムLT会 #1
    まとめ
    KMMは今後も期待が高まるフレームワークです。
    使いこなす難易度は高そうですが、
    新規開発の機会があれば導入を検討しようと思います!

    View Slide

  22. ランチタイムLT会 #1
    ご静聴ありがとうございました

    View Slide