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
SwiftUI + Kotlin Multiplatform 開発で見えた長所と短所
Search
swiftty
September 02, 2023
Technology
2
4.9k
SwiftUI + Kotlin Multiplatform 開発で見えた長所と短所
swiftty
September 02, 2023
Tweet
Share
More Decks by swiftty
See All by swiftty
iOS 18 から追加された SwiftUI の傾向について調べてみる
swiftty
3
260
Flutter アプリのリリースフローを考える
swiftty
0
140
Meet BrowserEngineKit
swiftty
0
1.4k
Cloud-managed certificates へ移行した話
swiftty
0
270
同じアプリを Flutter と SwiftUI で書いてみる
swiftty
0
370
Swift Package Manager へ移行した話
swiftty
0
440
SwiftLint にコントリビュートする
swiftty
1
4.4k
SwiftUI でリスト要素のインプレッションを計測する
swiftty
0
440
個人開発アプリでの Swift Macros 紹介
swiftty
0
520
Other Decks in Technology
See All in Technology
Jetpack Composeで始めるServer Cache State
ogaclejapan
2
160
権威ドキュメントで振り返る2024 #年忘れセキュリティ2024
hirotomotaguchi
2
730
バクラクのドキュメント解析技術と実データにおける課題 / layerx-ccc-winter-2024
shimacos
2
1k
watsonx.ai Dojo #5 ファインチューニングとInstructLAB
oniak3ibm
PRO
0
160
ずっと昔に Star をつけたはずの思い出せない GitHub リポジトリを見つけたい!
rokuosan
0
150
LINEヤフーのフロントエンド組織・体制の紹介【24年12月】
lycorp_recruit_jp
0
530
podman_update_2024-12
orimanabu
1
260
生成AIのガバナンスの全体像と現実解
fnifni
1
180
株式会社ログラス − エンジニア向け会社説明資料 / Loglass Comapany Deck for Engineer
loglass2019
3
31k
UI State設計とテスト方針
rmakiyama
2
310
Oracle Cloudの生成AIサービスって実際どこまで使えるの? エンジニア目線で試してみた
minorun365
PRO
4
270
Microsoft Azure全冠になってみた ~アレを使い倒した者が試験を制す!?~/Obtained all Microsoft Azure certifications Those who use "that" to the full will win the exam! ?
yuj1osm
1
110
Featured
See All Featured
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
Into the Great Unknown - MozCon
thekraken
33
1.5k
Documentation Writing (for coders)
carmenintech
66
4.5k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
2
290
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
28
900
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
45
2.2k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
1.9k
Faster Mobile Websites
deanohume
305
30k
Fireside Chat
paigeccino
34
3.1k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.3k
How To Stay Up To Date on Web Technology
chriscoyier
789
250k
Transcript
© 2023 Wantedly, Inc. SwiftUI + Kotlin Multiplatform 開発で 見えた長所と短所
iOSDC Japan 2023 スポンサーセッション Sep. 2 2023 - ウォンテッドリー株式会社 / 林達也
自己紹介 id/tatsuya_hayashi_ar swiftty © 2023 Wantedly, Inc. ウォンテッドリー株式会社 2023 年
3 月〜 Wantedly Visit の iOS アプリの開発
今日話すこと 前提 • iOS エンジニアで Kotlin Multiplatform (KMP) には触れたことがない •
過去のプロダクトは基本 UIKit で SwiftUI は部分的な導入程度 話すこと • KMP や SwiftUI での開発の際にどのような取り組みがあったかを紹介 ◦ プロフィールリニューアルについて ◦ SwiftUI 事例 ◦ KMP と Swift/SwiftUI の組み合わせ © 2023 Wantedly, Inc.
はじめに © 2023 Wantedly, Inc.
プロフィールリニューアル プロジェクト • 各プラットフォームでのプロフィール体験を 揃える • ウォンテッドリーではもともと KMP を採用し てマルチプラットフォームでの開発を行って
いた ◦ Android が先行していたため KMP 側の実装は完了していた 🎉 • SwiftUI の採用 🎉 © 2023 Wantedly, Inc. 引用: https://www.wantedly.com/companies/wantedly/post_articles/489565
SwiftUI の採用 • 今までも設定画面など部分的な導入はあっ た • 今回のリニューアルでは SwiftUI で 実現できるのかの検証も含めて始まった
© 2023 Wantedly, Inc.
KMP とは • Kotlin Multiplatform • ビジネスロジックを共通化 • UI は各プラットフォームで実装
© 2023 Wantedly, Inc. 引用: https://kotlinlang.org/lp/multiplatform/
KMP とは • Kotlin Multiplatform • ビジネスロジックを共通化 • UI は各プラットフォームで実装
© 2023 Wantedly, Inc.
ビジネスロジックの共通化 Reactor • 単方向データフローアーキテクチャを採用 ◦ View → Action → (Mutation)
→ State → View → … ◦ アプリケーション全体でひとつの状態管理ではなく集約されたビュー単位で状態管理 • Kotlin で定義されたクラスなので ObservableObject に適合していない ◦ 後付けで ObservableObject が要求する objectWillChange を 実装するのは大変 © 2023 Wantedly, Inc.
ビジネスロジックの共通化 Reactor • 単方向データフローアーキテクチャを採用 ◦ View → Action → (Mutation)
→ State → View → … ◦ アプリケーション全体でひとつの状態管理ではなく集約されたビュー単位で状態管理 • Kotlin で定義されたクラスなので ObservableObject に適合していない ◦ 後付けで ObservableObject が要求する objectWillChange を 実装するのは大変 © 2023 Wantedly, Inc. → Swift 側で Reactor をラップする
SwiftUI とReactor © 2023 Wantedly, Inc.
SwiftUI とReactor © 2023 Wantedly, Inc.
SwiftUI とReactor © 2023 Wantedly, Inc. → 以降は通常の SwiftUI と同じ
SwiftUI とReactor © 2023 Wantedly, Inc. → 以降は通常の SwiftUI と同じ
SwiftUI とReactor © 2023 Wantedly, Inc. → 以降は通常の SwiftUI と同じ
SwiftUI 事例 プロフィールヘッダー © 2023 Wantedly, Inc.
プロフィールヘッダー © 2023 Wantedly, Inc. UIKit でもよくある UI • コンテンツをスクロールするとヘッダーが縮む
• タブを切り替えたらヘッダーはそれに追従する
プロフィールヘッダー SwiftUI ではどうする? • ScrollView のスクロールを起点にレイアウトの制御を行いたい • SwiftUI の ScrollView
の問題 ◦ contentInset が調整できない ◦ オフセットを監視できない ◦ オフセットを変更できない © 2023 Wantedly, Inc.
プロフィールヘッダー SwiftUI ではどうする? • contentInset が調整できない → 空のビューでヘッダー分コンテンツの開始位置をずらす? • オフセットを監視できない
→ 子要素を GeometryReader で監視? • オフセットを変更できない → ScrollViewReader を使って scroll ならできる? • 最終的にオフセットをもとにヘッダービューの高さを変更すれば 当初のレイアウトを実現できそう 💭 © 2023 Wantedly, Inc.
プロフィールヘッダー © 2023 Wantedly, Inc.
プロフィールヘッダー © 2023 Wantedly, Inc. TabView を page スタイルで表示
プロフィールヘッダー © 2023 Wantedly, Inc. 各 content 内の ScrollView に高さ
0 で設置した ビューの位置をコンテンツの開始位置として anchorPreference で監視
プロフィールヘッダー © 2023 Wantedly, Inc. 各 content 内の ScrollView に高さ
0 で設置した ビューの位置をコンテンツの開始位置として anchorPreference で監視 overlayPreferenceValue でその位置をもとに ヘッダーの高さを算出しオーバーレイで重ねる
プロフィールヘッダー © 2023 Wantedly, Inc. オフセットが変化するたびに選択されたタブ以外の スクロール位置を scrollTo で同期させる
プロフィールヘッダー © 2023 Wantedly, Inc.
プロフィールヘッダー © 2023 Wantedly, Inc. → 思ったより素直なコードで実現できた 🎉
プロフィールヘッダー 良かった点 • 複雑なレイアウトを SwiftUI でシンプルに実現 ◦ UIKit なら数百行↑ 悪かった点
• ScrollView と List で挙動が変わる ◦ scrollTo の対象(ビュー単位、セル単位) • OS バージョンでの挙動の違いやパフォーマンスの観点でリリース間際まで格闘 ◦ 検証時は GeometryReader/onPreferenceChange を利用 ◦ safeAreaInset なども試したがその領域の奥へのインタラクションが反応しないなど問 題あり © 2023 Wantedly, Inc.
Xcode Previews © 2023 Wantedly, Inc.
Xcode Previews Wantedly Visit アプリ • Preview を積極的に活用して開発 ◦ 動作確認しやすいのでチームで自然とそうなった
• Feature Modules + KMP 構成(に移行中) ◦ ビジネスロジック(KMP)がビルド済みの XCFramework ◦ 依存の少ない新規 Profile モジュール • Preview 時は AnySwiftUIReactor に任意の State を設定してパターンを用意 © 2023 Wantedly, Inc.
Xcode Previews © 2023 Wantedly, Inc.
Xcode Previews © 2023 Wantedly, Inc.
Xcode Previews © 2023 Wantedly, Inc.
Xcode Previews 良かった点 • ビルド時間がほぼなく快適な体験 • 任意の State の注入によるパターンの確認しやすさ 悪かった点
• 任意の State を注入できるため、コンポーネントの適切な設計は 要検討 ◦ State のバケツリレー ▪ どこまでまとまったデータで扱うか、どこでプリミティブな値で扱うか © 2023 Wantedly, Inc.
KMP を Swift で扱う際の短所 © 2023 Wantedly, Inc.
KMP を Swift で扱う際の短所 • ネストされた型の階層の制限 • sealed class の網羅性チェック
© 2023 Wantedly, Inc.
KMP を Swift で扱う際の短所 • ネストされた型の階層の制限 • sealed class の網羅性チェック
© 2023 Wantedly, Inc.
ネストされた型の階層の制限 © 2023 Wantedly, Inc. KMP は Objective-C のモジュールを生成する
ネストされた型の階層の制限 © 2023 Wantedly, Inc. KMP は Objective-C のモジュールを生成する →
swift_name が複数階層をサポートしていない
ネストされた型の階層の制限 © 2023 Wantedly, Inc. Swift で見ると3階層以降はまとめられてしまう Swift だと型推論を活かして `.`
の左側は省略する ことが多い 階層が定義通りなら KMP の場合でも省略できるが …
KMP を Swift で扱う際の短所 • ネストされた型の階層の制限 • sealed class の網羅性チェック
© 2023 Wantedly, Inc.
sealed class の網羅性チェック © 2023 Wantedly, Inc. Swift では default
が必要になる
sealed class の網羅性チェック © 2023 Wantedly, Inc. Enum を再定義しコンパイルタイムで検知できるよう にインターフェースを用意
sealed class の網羅性チェック © 2023 Wantedly, Inc. Enum を再定義しコンパイルタイムで検知できるよう にインターフェースを用意
※ ライブラリ管理の移行が落ち着いたら自動生成などを検討 https://github.com/icerockdev/moko-kswift → 利用するときは網羅性チェックが効くように 🎉
まとめ KMP と SwiftUI • 100% SwiftUI でリニューアルを実現 🎉 •
KMP も SwiftUI の組み合わせも(癖はありつつ)体験は 👍 • Android も含めたモバイル開発チームの連携で大きくつまづくこともなかった 🤝 © 2023 Wantedly, Inc.
ご清聴ありがとうございました © 2023 Wantedly, Inc.
© 2023 Wantedly, Inc.