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, TCA, KMPを用いた 新規動画配信アプリ 「ABEM...
Search
Tomu Obata
April 15, 2024
Technology
0
1k
少数チームで挑む: SwiftUI, TCA, KMPを用いた 新規動画配信アプリ 「ABEMA Live」の開発について
https://cyberagent.connpass.com/event/307949/
Tomu Obata
April 15, 2024
Tweet
Share
More Decks by Tomu Obata
See All by Tomu Obata
TCAとKMPを用いた新規動画配信アプリ 「ABEMA Live」の設計
tomu28
2
330
モジュール分割した開発での知見とテーマ切り替えやUICatalogについて
tomu28
1
880
Other Decks in Technology
See All in Technology
AWS CDKでデータリストアの運用、どのように設計する?~Aurora・EFSの実践事例を紹介~/aws-cdk-data-restore-aurora-efs
mhrtech
4
650
Datachain会社紹介資料(2024年11月) / Company Deck
datachain
3
16k
ガバメントクラウド単独利用方式におけるIaC活用
techniczna
3
270
チームを主語にしてみる / Making "Team" the Subject
ar_tama
4
310
とあるユーザー企業におけるリスクベースで考えるセキュリティ業務のお話し
4su_para
3
320
君は隠しイベントを見つけれるか?
mujyun
0
290
急成長中のWINTICKETにおける品質と開発スピードと向き合ったQA戦略と今後の展望 / winticket-autify
cyberagentdevelopers
PRO
1
160
顧客が本当に必要だったもの - パフォーマンス改善編 / Make what is needed
soudai
24
6.8k
プロダクト成長に対応するプラットフォーム戦略:Authleteによる共通認証基盤の移行事例 / Building an authentication platform using Authlete and AWS
kakehashi
1
150
一休.comレストランにおけるRustの活用
kymmt90
3
580
Amazon_CloudWatch_ログ異常検出_導入ガイド
tsujiba
4
1.6k
生成AIと知識グラフの相互利用に基づく文書解析
koujikozaki
1
140
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
664
120k
Optimizing for Happiness
mojombo
376
69k
Designing the Hi-DPI Web
ddemaree
280
34k
Why You Should Never Use an ORM
jnunemaker
PRO
53
9k
Building Better People: How to give real-time feedback that sticks.
wjessup
363
19k
For a Future-Friendly Web
brad_frost
175
9.4k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.2k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
Testing 201, or: Great Expectations
jmmastey
38
7k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
231
17k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Transcript
株式会社サイバーエージェント 小幡 十矛 少数チームで挑む: SwiftUI, TCA, KMPを用いた 新規動画配信アプリ 「ABEMA Live」の開発について 2024/04/15 CA.swift
#19 1
・2021年、株式会社サイバーエージェントに新卒入社。 ・2023年4月までAmebaブログのiOSアプリを作成。 ・2023年5月から「ABEMA Live」iOSアプリの開発リードをしています。 ・WWDC 2024現地参加予定!🇺🇸 名前:小幡 十矛(Obata Tomu) 自己紹介
https://x.com/_tomu28 https://github.com/tomu28 2
POINT 01 サービス説明 POINT 02 実装機能 POINT 03 開発体制, スケジュール
POINT 04 iOS側の技術構成, 使用ライ ブラリ POINT 05 技術選定理由 POINT 06 開発Tips POINT 07 さいごに 目次 3
サービス説明 4
「ABEMA Live」では、「ABEMA」で配信されるアーティストのライブ、 イベント、スポーツ興行、舞台など多彩なペイパービュー (PayPerView)コンテンツを、海外からでも購入できます。 第一弾として世界最大級の格闘技団体・ONE Championshipの日本大会 をタイ、フィリピン、韓国にて同時生中継することが決定 https://www.onefc.com/jp/events/one165/ サービス説明 5
実装機能 6
ホーム/お知らせ/マイページ の3タブ構成 海外向け、PPV動画配信、 ログイン機能あり 実装機能 7
ユーザーログイン機能 ログイン アカウント登録 アカウント削除 ログインせずに使用する パスワードリセット 実装機能 8
ホーム 実装機能 9
番組詳細 実装機能 10
プレイヤー 実装機能 11
お知らせ一覧/詳細 実装機能 12
マイページ アカウントセッティング サービス概要 FAQ お問い合わせ ライセンスページ ログアウト 購入済み番組表示 → 番組詳細
実装機能 13
アプリ内課金 実装機能 14
その他 強制アップデート メンテナンスモード エラー画面 実装機能 15
その他 全画面タブレット対応 多言語対応(英語・タイ語・韓国語) Haptics feedback 実装機能 16
開発体制, スケジュール 17
2024/01/28に初回のイベントを実施 2023/10月までに基本的な機能を作り終え、 QA開始できる状態を目標に、開発を推進していた 2023/05から開発開始 開発体制としては、iOSエンジニア1~2人、Androidエンジニア1人 iOS、Android兼任1人 開発体制, スケジュール 18
iOS側の技術構成, 使用ライブラリ 19
VRT(pointfreeco/swift-snapshot-testing) KMP(Kotlin Multiplatform) TCA(The Composable Architecture) SPM(Swift Package Manager)でのライブラリ, モジュール管理
Feature単位でのマルチモジュール分割 プレイヤー周り:AVKit, UIKit。UIViewRepresentableを使い、UI側はフルSwiftUI Swift, SwiftUI, Swift Concurrency (iOS 16.6+) iOS側の技術構成, 使用ライブラリ 20
touchlab/SKIE vtourraine/AcknowList → ライセンス画面で使用 exyte/ScalingHeaderScrollView → 縮小する固定ヘッダーを備えたスクロール ビュー onevcat/Kingfisher siteline/swiftui-introspect
apple/swift-format realm/SwiftLint iOS側の技術構成, 使用ライブラリ 21
moko-resources → 画像は各OS毎の取得に変更 moko-kswift → SKIEに置き換え KMP-NativeCoroutines → SKIEに置き換え String
Catalog → KMP経由の文言取得に変更 現在は使っていないが一時期使っていたもの iOS側の技術構成, 使用ライブラリ 22
技術選定理由 23
1 メリット TCAを使用した理由 TCAに則って実装を進めることになるため、チームメンバー間で書き方のズレが少 なくなること KMP側でstateの値を更新するようにしても、iOS側でstateのbindやKMPのAction 発火、遷移周りの処理だったり、他ビューのAction伝搬などロジックもあるの で、TCAに乗っかった方が見通しが良くなる 2 許容したデメリット
開発当初はまだバージョンが0.x.x系ということもあり、推奨される書き方や破壊 変更に追従する必要があること → 開発途中で1.0.0がリリースされた 今後、メンバーが増減した時も対応しやすい 技術選定理由 24
TCA https://star-history.com/#pointfreeco/swift-composable- architecture&Date 技術選定理由 25
SKIEを使って、KMPで生成されたコードをswiftで扱いやすくする Presentation層のロジックまでKMP側で吸収 KMPで行っていること 技術選定理由 26
Presentation層の ロジックまでKMP側で吸収 KMPで行っていること 技術選定理由 27
Presentation層の ロジックまでKMP側で吸収 KMPで行っていること 技術選定理由 28
Presentation層の ロジックまでKMP側で吸収 KMPで行っていること 技術選定理由 29
Presentation層の ロジックまでKMP側で吸収 KMPで行っていること 技術選定理由 30
Presentation層の ロジックまでKMP側で吸収 KMPで行っていること 技術選定理由 31
suspend funやflowをSwiftで扱いやすくなる default case削除(sealed class/interfaceをenumとして扱えるようにする) SKIEを使って、KMPで生成されたコードをSwiftで扱いやすくする KMPで行っていること 技術選定理由 32
SKIEを使って、iOS側で定義していたenumを削除した例 技術選定理由 33
SKIEを使って、default caseを削除した例 技術選定理由 34
TCAとKMPの連携(アカウン ト新規登録画面の場合) 技術選定理由 35
TCAとKMPの連携(アカウン ト新規登録画面の場合) 技術選定理由 36
TCAとKMPの連携(アカウン ト新規登録画面の場合) 技術選定理由 37
元々、String Catalogを使っていたがKMP経由の 文言リソースアクセスに変更 まず、String Catalog を使っていた理由 脱SwiftGen出来る No.05 No.03 純正なので、Appleの改善に追
従出来ること No.04 No.04 非常にシンプルな形で文言管 理、多言語対応出来る No.01 No.01 生成物を分かりやすい形でGit 管理出来る No.0 No.05 今後対応言語が増えても追加 対応しやすい No.02 No.02 Xcode上でString Catalogが見 やすい No.06 技術選定理由 38
XcodeよりEdit -> Convert → To String Catalogs...で、 Localizable.stringsをLocalizable.xcstrings(String Catalog)に Migrateする。もしLocalizable.xcstringsが存在するため、Migrate
出来ないとエラーが出る場合、元々存在していた Localizable.xcstringsを削除後、Migrateする。 Localizable.stringsを更新する 文字列リソースのCSV(localize-strings.csv)を編集する String Catalogの更新手順 元々、String Catalogを使っていたがKMP経由の 文言リソースアクセスに変更 技術選定理由 39
元々、String Catalogを使っていたがKMP経由の 文言リソースアクセスに変更 先ほどの手順でString Catalogを 更新するデメリット マスターとなるCSVに文言変更がある度、 Convertを手動でする必要がある。ショートカ ットを当てればかなり楽なので、個人的には 許容
String Catalogに記載されているKey名に補完を 使えないので、Key名は直接入力するかコピー して入力する必要がある。TypeSafeではない 例: Text("Key名", bundle: .module) 技術選定理由 40
別アプリでも同じ文言を使いたい場合、それぞれconvertしないといけない。共通コンポ ーネントUI確認用のStyleCatalogAppと、同じ文言を使う必要はなかったため問題はな かった。 恐らくAppleの想定的にはconvertはstringsファイルからの移行時に一度のみ使って、今 後はString Catalogの機能で文言追加推奨していると推測。ただ、今回はCSVをMaster Dataとして扱うので、この部分はAppleの推奨する開発フローとは若干それてしまう。 デメリット 元々、String Catalogを使っていたがKMP経由の
文言リソースアクセスに変更 技術選定理由 41
moko-resourcesとは moko-resourcesは、Android、iOS、Web向けのKotlin Multiplatform プロジェクトにおいて、リソース(文字列、色、画 像、フォント)のアクセスを容易にするライブラリです moko-resourcesを辞めた主な理由 技術選定理由 https://github.com/icerockdev/moko-resources 42
iOSer的にクリティカルな不具合もメンテされていないのはリスク 画像の言語別出し分けは標準機能として提供されていなそうだった moko-resourcesを辞めた主な理由 技術選定理由 43
画像に各言語毎の文言埋め込むパターン 今後、ビジネス要件的に入ってくる可能性が高いという背景も考慮 画像の言語別出し分けは標準機能として提供されていなそうだった moko-resourcesを辞めた主な理由 技術選定理由 44
SwiftUIのViewだけを組む時のスピードが落ちる。VRTのしやすさ にも影響 Xcode Previewsで多言語のプレビューを同時に行う機能がある が、それらも使えない Xcode Previewのクラッシュ不具合(クリティカル)が長期間放置 されている:https://github.com/icerockdev/moko- resources/issues/396 iOSer的にクリティカルな不具合もメンテされていないの
はリスク moko-resourcesを辞めた主な理由 技術選定理由 45
SwiftUIIntrospectでtabViewの 表示・非表示を切り替えるように しています。 swiftui-introspect 技術選定理由 46
SwiftUIIntrospectでtabViewの 表示・非表示を切り替えるように しています。 swiftui-introspect 技術選定理由 47
開発Tips 48
KMP側ロジックのデバッグ POINT 01 iOS側で意図しないレスポンスが返ってくるAPI があった時は、KMP側のRequest部分でKMPの ログライブラリであるNapierログを入れ、 Requestとして使っている値をXcode上に表示す る POINT 02
もしくは、Proxymanで通信を可視化して調査し ていました Tips 49
iOS側で意図しないレスポンスが返ってく るAPIがあった時は、KMP側のRequest部 分でKMPのログライブラリであるNapier ログを入れ、Requestとして使っている値 をXcode上に表示する KMP側ロジックのデバッグ Tips https://github.com/AAkira/Napier 50
KMP側ロジックのデバッグ 実機でしたら、ProxymanのiOS App を入れて特定のホストをフィルター表 示して確認 https://proxyman.io/posts/2021-10- 17-Getting-Started-With-Proxyman- For-iOS もしくは、Proxymanで通 信を可視化して調査してい
ました https://proxyman.io/ Tips 51
実機でしたら、ProxymanのiOS Appを入れて特定のホストをフィルター表示して確認 https://proxyman.io/posts/2021-10-17-Getting-Started-With-Proxyman-For-iOS Debugビルドだと、Napier.d で手元のXcodeよりログ見れます が、Release ビルドだとNapier.d 出さないようにしているた め、Proxyman で確認していました。
Proxyman Tips 52
以下のようにScheme変更することでシミュレーター自体の設定を 変更しなくてもタイ語が表示される状態でRun出来ます。 App Region: Thailand App Language: Thia 変更点: Tips
53
以下のコードが必要 StoreKit 2でIAPイベントのロギングをする場合 Tips https://firebase.google.com/docs/analytics/measure-in-app-purchases?hl=ja#swift 54
TCAに則り、NavigationStackStoreをAppViewというルートとなるViewで 使用して遷移処理を組んでいた 問題なく処理は行えていたが 理想はタブ毎などの適切な粒度で NavigationStackStoreの使用をすること Tips 画面遷移 55
IAP購入時、ログインしているAppleアカウント(Sandbox環境の場合は、 Sandboxアカウント)の国情報によって、通貨表記が変わるという仕様 タイで登録している 場合は฿ 日本で登録している 場合は¥ Tips 56
パッケージ, モジュール構成 依存の流れとしては、MobileAppFeatureパッケージで MobileAppCoreパッケージを読み込むような形となる 04/ 共通する処理はMobileAppCoreパッケージに入れるようにしている 03/ Feature moduleはMobileAppFeatureとしてまとめて置いたほうが、TV対応な ども視野に入れた時、モジュールの責務が明確になるため良いと考えた。
TV対応する時は、TVAppFeatureパッケージを作るイメージ。 02/ MobileAppFeatureとMobileAppCoreパッケージを定義 01/ Tips 57
1~2ヶ月ほど続けると、Androidエンジニアの方もPRを出せるようになりました 毎日のPR振り返りで各PRを全員で見る会を行っていました iOSエンジニアとAndroidエンジニアの歩み寄り Tips 58
iOSエンジニアはSwift, Androidエンジニアは Kotlin側のレビューをしっかり行う iOSエンジニアとAndroidエンジニアの歩み寄り Tips 59
iOSエンジニアはSwift, Androidエンジニアは Kotlin側のレビューをしっかり行う iOSエンジニアとAndroidエンジニアの歩み寄り Tips 60
iOSエンジニアはSwift, Androidエンジニアは Kotlin側のレビューをしっかり行う iOSエンジニアとAndroidエンジニアの歩み寄り Tips 61
タブレット対応 Tips 62
タブレット対応 Tips 63
強制アプデ 不確実性への対応必須な部分とそうでは ない部分を都度切り分け、現実的なスケ ジュールで進められるよう適切に交渉。 ビジネス側や契約の都合で変化する恐れ がある部分は、審査不要で対応出来るよ うにFeatureFlagを差し込むなど柔軟にア プローチする。 POINT 04
使い所や適用範囲は要検討ですが、申請 不要でリアルタイムで制御出来るのは便 利。 POINT 03 不測の事態に備えて、FeatureFlagを入れ ておくことは大事 POINT 02 リアルタイム Remote Configでフラグ管 理して必要であれば、リアルタイム反映 するようにしました POINT 01 Tips 64
設定を変更した後に再度審査に出さないと処理が進まなかった 日本以外の配信国を追加した際、 年齢制限「なし」のままだと処理が進まない 審査時、ハマったポイント 65
Tips UIはフルSwiftUI, ロジックはKMPで吸収する 構成で、Crash数は0をキープ出来ています 66
POINT 01 共通ComponentはStyle Catalog Appで見れるようにし て、デザイナー確認 POINT 02 Haptics Feedback
Tips 67
Haptics Feedback プレイヤーで5秒スキップ時 最も軽いlight feedbackを設定する ホーム面から「サムネイル画像」or 「Check This Event」タップし、番組 詳細面に遷移するとき
最も軽いlight feedbackを設定する 課金成功し、アイテムが更新された タイミング Appleが用意しているSuccess feedbackを設定 する Tips 68
Live Activity Strict Concurrency CheckingをComplete にしてSwift 6を見据え た対応を進めていく 今後の展望 69
想定外のことも往々にして起き続ける 例えば、途中でアプリ名が変わったり… 共通コンポーネントなどはサービスのコードネームにしておいたので、 影響範囲は最小で済みました サービスネームを直で使っている箇所はコードには存在しなかったので、 「アプリアイコン」 「翻訳のマスターとなるスプシのデータ」「Keyが変わった場合その部分の修正」のみ 何があるか分からない 新規開発 70
CHECK 大切にしていた心構え 必要な要件と、1stリリースでは やらないことを明確にして進める 意識 完全新規の0→1は初めて。 CHECK 自分でとにかく触って、問題が あったら直してを繰り返す 本当に使いやすいアプリになって
いるか。プロダクトの品質を意識 まず作り切るのは大事だが、 良いアプリを作る視点 新規開発 71
さいごに 72
今回は開発全般について、特に概念的な部分を多く取り上げまし た。4/25ではTCA・KMPのアーキテクチャ構成での開発導入がしや すくなるように、関連する簡易的なサンプルプロジェクトを作成 し、ご紹介する予定です。 iOSアプリのアーキテクチャ設計~TCA実践編~ https://findy.connpass.com/event/315494/ 4/25も登壇するので、そちらもご確認いただけますと嬉しいです! 最後までご清聴いただきありがとうございました!! 73