Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Compose for iOS for ZOZOTOWN
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ねも
July 14, 2023
Programming
1.8k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Compose for iOS for ZOZOTOWN
ねも
July 14, 2023
More Decks by ねも
See All by ねも
Compose Multiplatform for iOS開発でぶつかった壁
kohei_inoue
0
1.8k
ノンプログラマのための ~アルゴリズムパズル プログラマのための数学パズル入門~
kohei_inoue
0
93
ノンデザイナーズ・デザインブックを読んだので名刺作ってみた
kohei_inoue
0
99
Compose Multiplatform for iOSで音声再生しようぜ!!
kohei_inoue
0
360
夏 × Jetpack Compose
kohei_inoue
0
95
Other Decks in Programming
See All in Programming
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
610
不変条件と整合性境界—ビジネスが決める設計判断と実現パターン / Invariants and Consistency Boundaries
nrslib
14
5.9k
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.5k
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
350k
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
640
エンジニアと一緒にテストコードの設計と実装を改善した話
mototakatsu
0
230
OSもどきOS
arkw
0
590
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
300
TAKTでAI駆動開発の品質を設計する
j5ik2o
7
1.5k
A2UI という光を覗いてみる
satohjohn
1
160
これからAgentCoreを触る方へトレンドはGatewayです
har1101
2
310
Featured
See All Featured
For a Future-Friendly Web
brad_frost
183
10k
30 Presentation Tips
portentint
PRO
1
330
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
400
Art, The Web, and Tiny UX
lynnandtonic
304
22k
The Curse of the Amulet
leimatthew05
2
13k
WENDY [Excerpt]
tessaabrams
11
38k
The SEO identity crisis: Don't let AI make you average
varn
0
500
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Color Theory Basics | Prateek | Gurzu
gurzu
0
370
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
370
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Transcript
Compose for iOS for ZOZOTOWN 2023/07/11 ZOZO Tech
Meetup - iOS/Android 株式会社ZOZO ZOZOTOWN開発本部 ZOZOTOWNアプリ部 Android1ブロック 財部彰太 ZOZOTOWN開発本部 ZOZOTOWNアプリ部 Android2ブロック 井上晃平 Copyright © ZOZO, Inc. 1
© ZOZO, Inc. 株式会社ZOZO ZOZOTOWN開発本部 ZOZOTOWNアプリ部 Android1ブロック 財部 彰太 食べる事が好きです。
2
© ZOZO, Inc. 株式会社ZOZO ZOZOTOWN開発本部 ZOZOTOWNアプリ部 Android2ブロック 井上 晃平
最近はワンパンマンにハマっていて、ONE先生版と村田先 生版の両方を読み返した 温泉旅館にいくために、そろそろ自動車免許が欲しい 3
© ZOZO, Inc. アジェンダ 1. 発表内容に関する注意と登壇の目的 2. Compose for iOSの基礎知識
2.1. JetBrainsが作るマルチプラットフォームの世界 2.2. Compose for iOSとは 2.3. レンダリング 2.4. Compose for iOSの優れている点 2.5. 今後注意したい動向 3. ZOZOTOWNをCompose for iOSで作った 3.1. 今回作ったもの 3.2. カルーセル部分の作成 3.3. スライダー部分の作成 3.4. それ以外はハリボテです 4. まとめ 4
© ZOZO, Inc. 注意 Compose for iOSは2023年7月現在alpha版 -> 今後大きな変更が加わる可能性がある
目的 すぐ仕事で使ってみてください!というよりは、今後の可能性をお伝えしたい。 フィードバック窓口 https://github.com/JetBrains/compose-multiplatform/issues 1 発表内容に関する注意と登壇の目的 KotlinConf’23 https://kotlinconf.com/talks/ 5
© ZOZO, Inc. 6 Compose for iOSの基礎知識
© ZOZO, Inc. 7 JetBrainsが作る マルチプラットフォームの世界
© ZOZO, Inc. 2.1 JetBrainsが作るマルチプラットフォームの世界 • Kotlin Multiplatform ◦ 複数のプラットフォームでKotlinで書かれたコードを共有する技術
◦ 2023年7月現在beta版であり、ドキュメントによるともうほぼstableとのこと • Kotlin Multiplatform for mobile(KMM) ◦ Kotlin Multiplatformのうち、モバイルに特化した場合の呼称 ◦ データ層のコードや、ViewModelなど、可能な限りの機能をKotlinで作成し、共有する ◦ UIの記述はiOS/Android 各プラットフォームに任せている • Compose Multiplatform ◦ AndroidのUIを宣言的に作成できるJetpack Composeを用いて、Desktop, Web, Androidといったプラットフォー ムのUIを記述できるようにするための仕組み Kotlin Multiplatform https://kotlinlang.org/docs/multiplatform.html Compose Multiplatform https://www.jetbrains.com/ja-jp/lp/compose-multiplatform/ 8
© ZOZO, Inc. 9 Compose for iOSとは
© ZOZO, Inc. Compose MultiplatformのiOSへの対応がalpha版に!! Compose Multiplatform https://www.jetbrains.com/ja-jp/lp/compose-multiplatform/ 10 Button(
onClick = { //hogehoge } ) { Text("Hello $platform") } 2.2 Compose for iOSとは
© ZOZO, Inc. compose-multiplatform-ios-android-template https://github.com/JetBrains/compose-multiplatform-ios-android-template/#readme 11 2.2 Compose for iOSとは
© ZOZO, Inc. 2.2 Compose for iOSとは Compose Multiplatformと Kotlin
Multiplatform for mobileを組み合わせることで、モバイ ルアプリ開発のネットワーク通信からUIの記述までの全範囲 をKotlinで作成し、共有することが可能に! The Kotlin Blog https://blog.jetbrains.com/ja/kotlin/2023/05/compose-multiplatform-for-ios-is-in-alpha/ 12
© ZOZO, Inc. 13 レンダリング
© ZOZO, Inc. 2.3 レンダリング • Android ◦ 従来の形でレンダリングされる
• iOS ◦ Skikoによってレンダリングされる ◦ Skiko ▪ SkiaをKotlin Multiplatformの中で使えるようにしたもの ◦ Skia ▪ Googleによって作成されたオープンソースの2Dグラフィックスライブラリ ▪ Chrome、Android、Flutterなど様々なハードウェアやソフトウェアプラットフォームで動作する JetBrains/Skiko https://github.com/JetBrains/skiko Skia https://skia.org/ Shader compilation jank https://docs.flutter.dev/perf/shader 14
© ZOZO, Inc. 2.3 レンダリング • FlutterはSkiaを使用した場合、レンダリングパフォーマンス上の課題が発生していた ◦ Compose for
iOSにおいても、Skiaを使用することによるレンダリングパフォーマンスの課題を持つのではない か • KotlinConfの発表(25分あたり)でも、16msの画面の停止を観測したとの解説がある ◦ 今後2msまで縮めていくとのこと 15 Compose Multiplatform on iOS by: Sebastian Aigner and Nikita Lipsky https://www.youtube.com/watch?v=FWVi4aV36d8 Shader compilation jank https://docs.flutter.dev/perf/shader
© ZOZO, Inc. 16 Compose for iOSの優れている点
© ZOZO, Inc. 2.4 優れている点① Jetpack ComposeのAPIがそのまま使える • Android開発で用いるJetpack ComposeのAPIそ
のものがiOSでも動作する • 作成したComposableが無駄にならない The Kotlin Blog https://blog.jetbrains.com/ja/kotlin/2023/05/compose-multiplatform-for-ios-is-in-alpha/ 17 @Composable fun App() { MaterialTheme { var showImage by remember { mutableStateOf(false) } Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { Button(onClick = { showImage = !showImage }) { Text("Toggle image") } AnimatedVisibility(showImage) { Image( painterResource("compose-multiplatform.xml"), "Compose Multiplatform Logo" } } } } import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material.Button import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.Alignment import androidx.compose.material.Text import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.painterResource
© ZOZO, Inc. 2.4 優れている点① Jetpack ComposeのAPIがそのまま使える The Kotlin Blog
https://blog.jetbrains.com/ja/kotlin/2023/05/compose-multiplatform-for-ios-is-in-alpha/ 18
© ZOZO, Inc. 2.4 優れている点② 相互運用性が高い • UIKitView ◦ iOS側の、地図、WebView、メディアプレイヤー、カメラといったプラットフォーム固有のウィジェットをComposeの
なかに組み込むことができる • ComposeUIViewController ◦ ComposeをSwift UIアプリケーションに埋め込むことができる →段階的な移行が可能に The Kotlin Blog https://blog.jetbrains.com/ja/kotlin/2023/05/compose-multiplatform-for-ios-is-in-alpha/ 19
© ZOZO, Inc. 2.4 優れている点② 相互運用性が高い ComposeUIViewControllerを使うとiOSネイティブとの接続も簡単 The Kotlin Blog
https://blog.jetbrains.com/ja/kotlin/2023/05/compose-multiplatform-for-ios-is-in-alpha/ 20 @main struct iOSApp: App { var body: some Scene { WindowGroup { ZStack { Color.white.ignoresSafeArea(.all) // status bar color ContentView() }.preferredColorScheme(.light) } } } struct ContentView: View { var body: some View { ComposeView() .ignoresSafeArea(.all, edges: .bottom) } } struct ComposeView: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> UIViewController { Main_iosKt.MainViewController() } func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} } iOSプロジェクト側(iosAppパッケージ)
© ZOZO, Inc. fun MainViewController() = ComposeUIViewController { App() }
@Composable fun App() { MaterialTheme { Screen() } } @Composable fun Screen() { // 実際のホーム画面を構成するコード } 2.4 優れている点② 相互運用性が高い sharedモジュール/iosMainパッケージ sharedモジュール/commonMainパッケージ ComposeUIViewControllerが iOSネイティブとComposeを接続!!! compose-multiplatform-ios-android-template https://github.com/JetBrains/compose-multiplatform-ios-android-template/
© ZOZO, Inc. 22 今後注意したい動向
© ZOZO, Inc. 2.5 今後注意したい動向 テーマ、デザインの方向性が未確定 • Compose for iOSはキャンバスベースのレンダリング
◦ iOSとAndroidアプリケーションはどちらも同じように表示される • 現状Compose Multiplatformは全てのプラットフォームでMaterialのウィジェットが適用されている • ターゲットのプラットフォームの外観にUIを寄せていく仕組みを作るのか、統一的なUIにしていくかは未確定とのこ と => もしCompose for iOSがiOSへデザインを寄せずにAndroidライクなデザインのみを提供することになったら、Stable になっても導入は難しそう The Kotlin Blog https://blog.jetbrains.com/ja/kotlin/2023/05/compose-multiplatform-for-ios-is-in-alpha/ 23
© ZOZO, Inc. 24 ZOZOTOWNをCompose for iOSで作った
© ZOZO, Inc. 25 今回作ったもの
© ZOZO, Inc. 3.1 今回作った物 Compose Multiplatformにより一つのコードで、iOSとAndroid版のホーム画面を作成 26 iOS版 Android版
© ZOZO, Inc. 27 動画だとこんな感じ
© ZOZO, Inc. 28 • カルーセルをスライドした時のテキストのアニメーションの部分 •
複雑なUIである、商品のGrid状のスライダー → 作れます。そう、Compose for iOSならね。 実装上のポイント
© ZOZO, Inc. 29 カルーセル部分の作成
© ZOZO, Inc. 3.2 カルーセル部分の作成 • HorizontalPagerを使用 •
要素のスライド時に、タイトルとサブテキストだけ アニメーション付きでスライドインする 30
© ZOZO, Inc. カルーセルの作成 31 • HorizontalPagerで横方向のカルーセルを実装する。ページの 設定、ページ間のマージン、ページの表示範囲等を引数で設定 している。 •
Android開発の時と同じ書き方でカルーセルを実装できる。 @Composable fun Carousel( modifier: Modifier = Modifier, items: List<CarouselItemModel>, ) { val pagerState = rememberPagerState() Column(/* Columnの諸設定 */) { HorizontalPager( pageCount = items.size, state = pagerState, contentPadding = PaddingValues(horizontal = 20.dp), pageSpacing = 12.dp, ) { page -> CarouselItem(/* 後述します */) } // DotsIndicatorの実装 } }
© ZOZO, Inc. カルーセルの要素の作成 32 • BoxWithConstraintsでComposableの横幅を計測しつつ、要素を重ねるよ うに配置していく • 引数で受け取ったpageOffsetFractionと、BoxWithConstraintsで計測した
横幅で、カルーセルのスライド幅を算出している • Modifier.graphicsLayerで、カルーセル自体 < タイトル < サブテキストの順 番でスライドスピードが早くなるようなアニメーションを設定している @Composable fun CarouselItem( // その他の引数 pageOffsetFraction: Float, ) { BoxWithConstraints(/* BoxWithConstraintsの諸設定 */) { val width = LocalDensity.current.run { constraints.maxWidth.toDp() } val pageOffset = width.value * pageOffsetFraction Image(/* カルーセルの画像 */) Column(/* タイトルとサブテキストを保持する Column */) { Text( modifier = Modifier .graphicsLayer { translationX = - pageOffset * 1.8f }, // タイトルのその他の設定 ) Text( modifier = Modifier .graphicsLayer { translationX = - pageOffset * 2.2f }, // サブテキストのその他の設定 ) } } }
© ZOZO, Inc. 33 スライダー部分の作成
© ZOZO, Inc. 3.3 スライダー部分の作成 34 • LazyHorizontalGridを使用 • GridCells.Fixedで2を設定することで、2行の横方
向のスライダーを実現
© ZOZO, Inc. スライダーの作成 35 • 引数でrowFixedCountとして受け取った行数を、 LazyHorizontalGridのrowsで渡す • LazyHorizontalGridの内部で、SliderItemというスライダーの要
素のコンポーザブルを配置する @Composable fun Slider( // その他引数 sliderItemModels: List<sliderItemModel>, rowFixedCount: Int, ) { Column(/* Column 設定 */) { Text(/* セクションのタイトル(アイテムランキング)表示 */) LazyHorizontalGrid( // Modifier設定 rows = GridCells.Fixed(rowFixedCount), ) { sliderItemModels.forEachIndexed { index, model -> item { SliderItem(/* 後述します */) } } } } }
© ZOZO, Inc. スライダーの要素の作成 36 • SliderItemModelとして表示要素(ブランド名、値段、etc..)を受 け取る • RowとColumnを組み合わせた基本的なレイアウト
@Composable fun SliderItem( model: SliderItemModel, // その他引数 ) { Column( modifier = modifier.width(120.dp) ) { Image(/* 商品画像 */) Column( modifier = Modifier.fillMaxWidth() ) { Row(/* 1行目のブランド名の部分 */) { Text(/* Brand Name */) } Row(/* 2行目の値段とハートの部分 */) { Text(/* 値段 */) Image(/* ハート */) } } } }
© ZOZO, Inc. 37 それ以外はハリボテです
© ZOZO, Inc. 3.4 それ以外はハリボテです 38 • 実際に押せたり検索できたりはせず、見た目だけ作成 • Columnの内部のZOZOTOWNのロゴを保持しているRowで
は、左端のSpacerと、通知とカートのアイコンを保持するRow にweight(1f)を指定することでZOZOTOWNのロゴで余った部 分を等分している @Composable fun TopAppBar() { Column( modifier = Modifier .background(color = ZozoColor.GrayScaleFE) ) { Row(/* 設定 */) { Spacer(modifier = Modifier.weight(1f)) Icon(/* ZOZOTOWNのロゴ */) Row( modifier = Modifier.weight(1f) ) { /* 通知とカートのアイコン */ } } SearchBar(/* 検索バー */) TabLayout(/* すべて、シューズ、コスメのTabLayout */) } }
© ZOZO, Inc. 39 • これが画面に表示されるだけで、アプリのホーム画面がそ れっぽくなった • シンプルにRowに画像を3つ載せている @Composable
fun AttributeSelector( modifier: Modifier = Modifier ) { Row( modifier = modifier.padding(vertical = 12.dp) ) { Image(/* メンズ */) Image(/* レディース */) Image(/* キッズ */) } } メンズ、レディース、キッズの選択UI
© ZOZO, Inc. 40 完成!!
© ZOZO, Inc. 41 まとめ
© ZOZO, Inc. まとめ • KMMと合わせて、Kotlinエコシステムでアプリを作っていけるようになれば嬉しい。ワクワク。 • Swiftをほとんど書かず、Androidアプリを作ってる時と同じ感覚でiOSアプリを作れた。 • やっぱり両OSのコードを共通化できると嬉しい。
• カメラ等ネイティブの機能をふんだんに活用したりといったことは今回していないので、もしかしたら落とし穴はたくさんある かもしれない。 Kotlin Multiplatform https://kotlinlang.org/docs/multiplatform.html 42
None