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

Compose MutiPlatformで始めるクロスプラットフォーム開発(ライブラリ編)

akkie76
July 15, 2023

Compose MutiPlatformで始めるクロスプラットフォーム開発(ライブラリ編)

Shibuya.apk #43 で発表した資料になります。
https://shibuya-apk.connpass.com/event/288211/

akkie76

July 15, 2023
Tweet

More Decks by akkie76

Other Decks in Technology

Transcript

  1. Shibuya.apk #43
    ©2023 RAKUS Co., Ltd.
    Compose MultiPlatformで
    始めるクロスプラットフォーム開発
    ライブラリ編
    @akkiee76
    Shibuya.apk #43

    View Slide

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

    View Slide

  3. Shibuya.apk #43
    今日伝えたいこと
    Compose MultiPlatform で開発で主軸となる
    ライブラリの紹介

    View Slide

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

    View Slide

  5. Shibuya.apk #43
    Kotlin Multiplatform for Mobile (KMM)
    フレームワークイメージ

    View Slide

  6. Shibuya.apk #43
    Kotlin Multiplatform for Mobile (KMM)
    アーキテクチャイメージ
    Compose Multiplatform

    View Slide

  7. Shibuya.apk #43
    Compose MultiPlatform
    Compose Multiplatformは、Kotlinを使用して複数のプラットフォーム間でUI
    を共有するための宣言的なフレームワークです。JetBrainsとオープンソースの貢献
    者によって開発され、Jetpack Composeに基づいています。
    https://github.com/JetBrains/compose-multiplatform

    View Slide

  8. Shibuya.apk #43
    ここからは導入手順を紹介します

    View Slide

  9. Shibuya.apk #43
    開発に必要な環境
    ・ macOS
    ・ Android Studio
    ・ Xcode
    ・ JDK
    ・ Kotlin Multiplatform Mobile plugin
    ・ Kotlin plugin
    ・ CocoaPods dependency manager
    あとは brew install kdoctor を実行するだけ

    View Slide

  10. Shibuya.apk #43
    プロジェクト作成
    * Desktop版はIntelliJから作成可能

    View Slide

  11. Shibuya.apk #43
    プロジェクト作成(Compose Multiplatform Wizard)
    https://terrakok.github.io/Compose-Multiplatform-Wizard/

    View Slide

  12. Shibuya.apk #43
    プロジェクトビルド
    androidx.compose.material3 に対応

    View Slide

  13. Shibuya.apk #43
    基本的なライブラリ選定
    16種類のライブラリが選択可能

    View Slide

  14. Shibuya.apk #43
    開発の主軸になるライブラリの紹介
    ・ Voyager (navigation)
    ・ Ktrofit (HTTP client)
    ・ Koin (dependency injection)
    ・ SQLDelight (SQL)

    View Slide

  15. Shibuya.apk #43
    navigation 事情
    navigation-composeはサポートされていなかった。。
    https://github.com/JetBrains/compose-multiplatform/tree/master/tutorials/Navigation

    View Slide

  16. Shibuya.apk #43
    Voyager
    Screen クラスを継承して Content を作成します。
    class PostListScreen : Screen {
    @Composable
    override fun Content() {
    // ...
    }
    }
    data class PostDetailsScreen(val postId: Long) : Screen {
    @Composable
    override fun Content() {
    // ...
    }
    }

    View Slide

  17. Shibuya.apk #43
    Voyager
    LocalNavigator.currentOrThrow を使用して画面遷移することが可能。
    class PostListScreen : Screen {
    @Composable
    override fun Content() {
    // ...
    }
    @Composable
    private fun PostCard(post: Post) {
    val navigator = LocalNavigator.currentOrThrow
    Card(
    modifier = Modifier.clickable {
    navigator.push(PostDetailsScreen(post.id))
    // Also works:
    }
    ) {
    // ...
    }
    }
    }

    View Slide

  18. Shibuya.apk #43
    Voyager
    TopAppBar、BottomNavigationにも対応しており、
    navigation-composeのように実装することで実現可能。
    @Composable
    override fun Content() {
    Navigator(HomeScreen) { navigator ->
    Scaffold(
    topBar = { /* ... */ },
    content = { CurrentScreen() },
    bottomBar = { /* ... */ }
    )
    }
    }

    View Slide

  19. Shibuya.apk #43
    Ktrofit
    RetrofitのようなAPIで
    実装することが可能。
    https://foso.github.io/Ktorfit/
    interface UnsplashService {
    @GET("search/photos")
    suspend fun searchPhotos(
    @Query("query") query: String,
    @Query("page") page: Int = 1,
    @Query("per_page") perPage: Int = 1,
    @Query("client_id") clientId: String = "clientId"
    ): UnsplashSearchResponse
    companion object {
    private const val BASE_URL = "https://api.unsplash.com/"
    fun create(): UnsplashService {
    return ktorfit {
    baseUrl(BASE_URL)
    httpClient(HttpClient {
    install(ContentNegotiation) {
    json(Json { isLenient = true; ignoreUnknownKeys = true })
    }
    })
    converterFactories(
    FlowConverterFactory(),
    CallConverterFactory()
    )
    }.create()
    }
    }
    }

    View Slide

  20. Shibuya.apk #43
    Ktrofit (serialization)
    レスポンスをserializeするため、
    kotlinx-serializationも同時に導入します。
    https://github.com/Kotlin/kotlinx.serialization
    import kotlinx.serialization.SerialName
    import kotlinx.serialization.Serializable
    @Serializable
    data class UnsplashUser(
    val id: String,
    val name: String,
    val username: String,
    val bio: String?,
    @SerialName("profile_image")
    val profileImage: UnsplashProfileImage?,
    )

    View Slide

  21. Shibuya.apk #43
    Koin (dependency injection)
    injectionするmoduleを定義します。
    iOSとAndroidのそれぞれで定義する必要があります。
    https://insert-koin.io/docs/reference/koin-mp/kmp/
    private val searchViewModel = module { singleOf(::SearchViewModel) }
    private val searchRepository = module { singleOf(::SearchRepository) }
    fun appModule() = listOf(searchViewModel, searchRepository)
    // for iOS
    fun initKoin() {
    startKoin {
    modules(appModule())
    }
    }
    // for Android
    fun initKoin(appDeclaration: KoinAppDeclaration = {}) = startKoin {
    appDeclaration()
    modules(appModule())
    }

    View Slide

  22. Shibuya.apk #43
    Koin (dependency injection) Android
    Applicationクラスに初期化実装を行います。
    https://insert-koin.io/docs/reference/koin-mp/kmp/
    class MainApplication: Application(), KoinComponent {
    override fun onCreate() {
    super.onCreate()
    initKoin {
    androidContext(this@MainApplication)
    }
    }
    }
    class MainActivity : AppCompatActivity() {
    private val searchViewModel: SearchViewModel by inject()
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
    MainView(searchViewModel)
    }
    }
    }

    View Slide

  23. Shibuya.apk #43
    Koin (dependency injection) iOS
    Appクラスに初期化実装を行います。
    https://insert-koin.io/docs/reference/koin-mp/kmp/
    @main
    struct iOSApp: App {
    init() {
    AppModuleKt.initKoin()
    }
    var body: some Scene {
    WindowGroup {
    // content
    }
    }
    }
    struct ContentView: View {
    private let searchViewModel = AppModule().getSearchViewModel()
    var body: some View {
    // content
    }
    }

    View Slide

  24. Shibuya.apk #43
    .sqファイルでクエリを定義することで、
    実装コードからSQLが実行可能になります。
    SQLDelight (SQL)
    selectAll:
    SELECT *
    FROM hockeyPlayer;
    insert:
    INSERT INTO hockeyPlayer(player_number,
    full_name)
    VALUES (?, ?);
    insertFullPlayerObject:
    INSERT INTO hockeyPlayer(player_number,
    full_name)
    VALUES ?;
    val database = Database(driver)
    val playerQueries: PlayerQueries = database.playerQueries
    println(playerQueries.selectAll().executeAsList())
    // Prints [HockeyPlayer(15, "Ryan Getzlaf")]
    playerQueries.insert(player_number = 10, full_name = "Corey Perry")
    println(playerQueries.selectAll().executeAsList())
    // Prints [HockeyPlayer(15, "Ryan Getzlaf"), HockeyPlayer(10, "Corey
    Perry")]
    val player = HockeyPlayer(10, "Ronald McDonald")
    playerQueries.insertFullPlayerObject(player)

    View Slide

  25. Shibuya.apk #43
    まとめ
    ・ Compose Multiplatform Wizard を利用することで、
    簡単にライブラリ設定ができる!
    ・ まだまだ使い勝手が悪い点もあるが今後のアップデートに期待!

    View Slide

  26. Shibuya.apk #43
    ご静聴ありがとうございました

    View Slide