Slide 1

Slide 1 text

Chatwork株式会社 モバイルアプリケーション開発部 福井 章平 / 中山 龍 2023年9月3日 iOSDC Japan 2023 SwiftUIに適した 新アーキテクチャの導入に挑む

Slide 2

Slide 2 text

自己紹介 2 ● 名前:福井 章平 (@tinpay) ○ 2014年に Chatwork 入社 ● 役職:プロダクト本部    モバイルアプリケーション開発部    マネージャー ● 趣味 ○ 大阪のスパイスカレー屋さん巡り ○ ビール🍺

Slide 3

Slide 3 text

自己紹介 3 ● 名前:中山 龍 (@ryu_develop) ○ 2023年に Chatwork 新卒入社 ○ 社内最年少の21歳 ● 役職:プロダクト本部    モバイルアプリケーション開発部    Blancチーム メンバー ● 趣味 ○ サッカー観戦 ○ 昼寝

Slide 4

Slide 4 text

会社概要 4 会社名 Chatwork株式会社 代表取締役CEO 山本 正喜 グループ従業員数 411名(2023年6月末日時点) 所在地 東京、大阪 設立 2004年11月11日

Slide 5

Slide 5 text

コーポレートミッション 5 働くを もっと楽しく、 創造的に 人生の大半を過ごすことになる 「働く」という時間において、 ただ生活の糧を得るためだけではなく、 1人でも多くの人がより楽しく、 自由な創造性を存分に発揮できる社会を実現する

Slide 6

Slide 6 text

事業概要 6 *1 Chatworkセグメント以外の事業として、ESET社提供のセキュリティ対策ソフトウェア「ESET」の代理販売事業を展開。安定的な収益貢献となっている *2 Nielsen NetView 及びNielsen Mobile NetView Customized Report 2022年5月度調べ月次利用者(MAU:Monthly Active User)調査。 調査対象はChatwork、Microsoft Teams、Slack、LINE WORKS、Skypeを含む47サービスをChatwork株式会社にて選定 *3 2023年6月末時点 ● 国内最大級のビジネスチャット「 Chatwork」を中心に、複数の周辺サービスを展開 *1 ● ビジネスチャットのパイオニアであり国内利用者数 No.1*2、導入社数は 41.0万社*3を突破 ● 電話やメールから効率的なチャットへ、ビジネスコミュニケーションの変化を加速させプラットフォーム化を目指す

Slide 7

Slide 7 text

AGENDA アジェンダ 課題探しからリアーキテクチャまでの流れ 新アーキテクチャ「SVVS」とは? 1 2

Slide 8

Slide 8 text

課題探しからリアーキテクチャまでの流れ 8

Slide 9

Slide 9 text

Chatworkアプリの歴史 9 ファーストリリース (Titanium) ネイティブ版リリース CoreData → Realm ReactiveCocoa → RxSwift Swift化 Chatwork Live リアクション モバイルマルチアカウント リンクプレビュー iOS5 iOS16 2023年 2011年 2016年 2018年 2020年 2014年 ネイティブ版 実装開始 (Objective-C / ReactiveCocoa) AST ブックマーク ダークモード対応 モバイル広告 行動分析(TreasureData) iPad 2カラム対応 メッセージ閲覧制限 Google / Apple 認証 In-App Purchase GDPR対応 RxSwift → Combine Swift Concurrency SwiftUI Swift Package Manager Carthage CocoaPods XcodeGen Mantle → Codable 9年 モバイルの技術 Chatworkの新機能 長い歴史と 共に増える 技術的負債

Slide 10

Slide 10 text

課題探しからリアーキテクチャを進めるまでの流れ 10 ① 技術的負債を考えるワークショップ ② アーキテクチャを考えるワークショップ ③ 進め方を考えるワークショップ iOSアプリの課題を解決するため、 iOSチームで3回のワークショップを 行った

Slide 11

Slide 11 text

① 技術的負債を考えるワークショップ

Slide 12

Slide 12 text

① 技術的負債を考えるワークショップ 12 Chatworkアプリ内の技術的負債に関して、 具体的な課題や未解決事項をリストアップし、 開発メンバー全員がこれらの問題について共通の 理解を持つこと 目的 iOSチームメンバーでオンラインワークショップを行った

Slide 13

Slide 13 text

① 技術的負債を考えるワークショップ 13 💡技術的負債の13の種類ごとに、 課題に感じていることを 付箋に書いて貼る 💡課題に感じる理由を 付箋に書いて貼る 💡課題を解決するためのアイデアを 付箋に書いて貼り、 投票してディスカッション ref. Towards an Ontology of Terms on Technical Debt

Slide 14

Slide 14 text

① 技術的負債を考えるワークショップ 14 ワークショップで出てきた課題を整理し、開 発者の温度感、難易度をポイント付けした

Slide 15

Slide 15 text

① 技術的負債を考えるワークショップ 15 ● マルチスレッドによるデータ競合によるクラッシュや不具合が発生している ○ 現在はMVVMを採用しているが、描画周りが手続的に実装されていたり複雑な通知 経路があったりするため、クラッシュや不具合が発生しやすい構造になっている ● 依存関係が複雑で、モジュールとして切り出すことが困難 ● 既存のアーキテクチャが複雑であり、学習コストが高い ● 1箇所変更すると、別の箇所でデグレが発生してしまう リストアップされた課題 (優先度高いものを抜粋)

Slide 16

Slide 16 text

② アーキテクチャを考えるワークショップ

Slide 17

Slide 17 text

② アーキテクチャを考えるワークショップ 17 iOSアプリに関連する課題を分析し、組織の構造や 戦略を考慮に入れつつ、アプリのアーキテクチャ方 向性を検討すること 目的 iOSチームメンバーとコンサルをお願いしている @koher さんと、 大阪オフィスでワークショップを行った

Slide 18

Slide 18 text

② アーキテクチャを考えるワークショップ 18 1. データ競合によるクラッシュや不具合の軽減 2. これから導入を進めていく予定であるSwiftUI化の進めやすさ 3. 不具合やデグレ、変化に対する堅牢さ 4. 組織の戦略を迅速なサイクルで実行し、開発スピードを向上させること 考慮したポイント SVVSアーキテクチャ誕生 🎂

Slide 19

Slide 19 text

② アーキテクチャを考えるワークショップ 19 SVVSの詳細は後ほど… SVVSアーキテクチャ概要

Slide 20

Slide 20 text

③ 進め方を考えるワークショップ

Slide 21

Slide 21 text

③ 進め方を考えるワークショップ 21 開発メンバーが協力して、SVVSアーキテクチャの 導入プロセスを具体的に検討し、進め方について共 通の認識を持つこと 目的 iOSチームメンバーで、東京オフィスでワークショップを行った

Slide 22

Slide 22 text

③ 進め方を考えるワークショップ 22 💡リアーキテクチャに必要な 成果物を赤い付箋に書いて貼る 💡成果物を完成させるために 必要なタスクを 付箋に書いて貼る 成果物 タスク

Slide 23

Slide 23 text

③ 進め方を考えるワークショップ 23 💡タスクを優先度順に 並べ替える

Slide 24

Slide 24 text

③ 進め方を考えるワークショップ 24 ● タスクをどのように進めていくか開発メンバーで共通認識が持てた ● どれぐらい時間がかかりそうか、大まかに把握することができた ワークショップを終えて 現在は、iOSチームの開発プロセスに乗せてSVVS化を進めている では、SVVSとはどのようなアーキテクチャのか、詳細を説明していきいます

Slide 25

Slide 25 text

新アーキテクチャ「SVVS」とは? 25

Slide 26

Slide 26 text

SVVSとは

Slide 27

Slide 27 text

SVVSとは 27 Store View View State

Slide 28

Slide 28 text

SVVSとは 28 Store View View State 状態を管理する


Slide 29

Slide 29 text

SVVSとは 29 Store View View State 画面


Slide 30

Slide 30 text

SVVSとは 30 Store View View State プレゼンテーションロジック


Slide 31

Slide 31 text

各コンポーネントを詳しく...

Slide 32

Slide 32 text

32 Store

Slide 33

Slide 33 text

単一の情報源となる GlobalStateを管理する Storeの役割 33 プロパティとして保持する 取得・更新するメソッドを持つ 補足:GlobalState 画面間で共有される状態のこと ● 例) ユーザー情報 / チャット一覧など ※ 画面内などに閉じた状態(データ)ではない ● 例) 入力状態 / ボタンの無効化など SwiftUI化に重要なSingle Source of Truthを実現する

Slide 34

Slide 34 text

Storeの依存関係 34 Store ViewState 依存 N N ViewやViewStateには依存しない ViewStateから依存される ViewStateからStoreへの一方通行の依存関係となる Store は GlobalState を @Published private(set) var で保持 → ViewStateからの取得・購読はできるが、変更は Store内でし かできない

Slide 35

Slide 35 text

Storeのサンプル 35 GlobalStateを@Published private(set) var で保持している

Slide 36

Slide 36 text

Storeのサンプル 36 GlobalStateを管理(取得・更新)するためのメソッドを持つ

Slide 37

Slide 37 text

37 View State

Slide 38

Slide 38 text

Viewの状態を管理する Viewのアクションをメソッドで実装する ViewStateの役割 38 StoreのデータをViewの表示に適した形に修正して、自 身のプロパティに反映する 画面内の入力状態など、画面に閉じた状態もViewState 自身で管理する 注意:ViewModelではない ViewModelと比べてより「Viewの状態管 理」に注力した役割のため ViewState とい う命名になっている ボタンのアクションなど アクションとなるメソッドは戻り値を持たず、結果を ViewStateのプロパティに反映することでViewの更 新を行う 補足:状態の変更 ViewStateからStoreの状態を直接変更す ることはできないので、Store内のメソッ ドを呼び出すことでGlobalStateの更新を 行います

Slide 39

Slide 39 text

ViewStateの依存関係 39 Viewから依存され、Storeに依存する Store ViewState View 依存 依存 1 1 N N Viewのアクションに対応するメソッドは、必要に応じて Store内のメソッドを呼び出し、GlobalStateを更新する 必要に応じて依存先であるStoreの値を購読することで、 Viewに表示する値を常にStoreの状態と同期させる

Slide 40

Slide 40 text

ViewStateのサンプル 40 Viewを表示するためのプロパティを持つ Viewのアクションに対応するメソッドを持つ

Slide 41

Slide 41 text

ViewStateのサンプル Storeのデータを購読し、Viewの表示に適した形に修正 して、自身のプロパティに反映する 41

Slide 42

Slide 42 text

42 View

Slide 43

Slide 43 text

Viewの役割 43 Viewはロジックを持ち過ぎないようにするために イベント処理はViewStateのメソッドを呼ぶだけにする SVVS外の補足:画面遷移 画面遷移にはUIKitを使用する ChatworkはiOS14以降をサポートしていた り、iPad対応などもあり、画面遷移をSwiftUI に移行するのは困難 → UIHostingControllerと組み合わせ、UIKit で画面遷移を実装する SwiftUIで実装された画面 Viewは必ずViewStateを持つ (View ≠ Component) ViewStateを@StateObjectで保持する

Slide 44

Slide 44 text

ViewStateに依存する Viewの依存関係 44 ViewStateのプロパティを使って画面を表示する ViewState View 依存 1 1 ユーザーアクションによって、対応するViewState のメソッドを呼ぶ

Slide 45

Slide 45 text

Viewのサンプル 45 ViewStateを@StateObjectで保持する

Slide 46

Slide 46 text

Viewのサンプル 46 ViewStateのプロパティを使って画面を表示する ViewStateのメソッドを呼んでイベント処理をする

Slide 47

Slide 47 text

各コンポーネントの関係

Slide 48

Slide 48 text

依存関係

Slide 49

Slide 49 text

各コンポーネントの関係 49 1 1 N N Store ViewState View 依存関係 依 存

Slide 50

Slide 50 text

データの流れ

Slide 51

Slide 51 text

データの流れ 51 外部API 通信 Store ViewState View メソッド呼び出し 伝播 伝播 ユーザーアクションが 伝わる流れ データがリアクティブに 反映される流れ 更新後データ ユーザーアクション メソッド呼び出し

Slide 52

Slide 52 text

SVVS 3つの特徴

Slide 53

Slide 53 text

SVVS 3つ特徴 53 データフローに フォーカス シンプル リアクティブ

Slide 54

Slide 54 text

リアクティブ 54 リアクティブ 各レイヤー間のデータが 同期されている コードが減り・バグも減る 責務がわかりやすい SwiftUI向け データの同期処理を手続き的に書かなくてよくなる 本質的ではないコードが減る Storeを単一の情報源として Single Source of Truthを実現

Slide 55

Slide 55 text

シンプル 55 シンプル コアなコンポーネントも 3つだけ バグに強い 変更しやすい 開発スピードUP 複雑なものよりシンプルなものの方がバグに強い シンプルに作っておけば、後からの変更・方針転換がしやすい 習得コストが低い 小さなPRを作りやすい

Slide 56

Slide 56 text

データフローにフォーカス 56 データフローに フォーカス データがどう流れるかの 観点を重視 データ不整合の発生防止 Viewのロジックに特化したViewState Chatworkアプリの特性あっている Single Source of Truthを実現し、Storeを単一の情報源として扱う Single Source of Truthを実現するためにViewModelをより最適化 コア機能は「サーバーとの通信」であり、現状アプリの反省からデータが 必ず一方通行に流れる作りとなっている

Slide 57

Slide 57 text

SVVSサンプルコード https://github.com/chatwork/svvs-sample.git 57

Slide 58

Slide 58 text

まとめ 58

Slide 59

Slide 59 text

まとめ 59 ● 課題探しからリアーキテクチャまでの流れ ○ まずは課題を言語化し、チーム内で共通認識をもった ○ 技術戦略と組織戦略、両方を加味してアーキテクチャを考えた ○ 現在はタスク分解しながら、チームで考えて実装を進めている ● 新アーキテクチャ「SVVS」とは? ○ Store - View - ViewState の略称 ○ SwiftUI化に重要なSingle Source of Truthを実現 ○ 3つの特徴 ■ リアクティブ / シンプル / データフローにフォーカス ○ まだ始まったばかりで、今からSVVS化をガンガン進めていきます

Slide 60

Slide 60 text

最後に2つ告知させてください 60

Slide 61

Slide 61 text

イベント申し込み 1つ目!オンラインイベントを開催します! 『モバイルアプリ部を徹底解剖!DAU100万の『Chatwork』を 支えるモバイルチームの現場とは?』というタイトルでイベント を開催します🎉開発メンバーのパネルトークがあり、どのように 課題に向き合って開発を進めているかお伝えできればと思います!

Slide 62

Slide 62 text

iOSエンジニア採用 2つ目!Chatworkでは仲間を募集しています! もう少し詳しく今日の話を聞きたい方、興味を持っていただけた方は 気軽にご連絡ください!

Slide 63

Slide 63 text

働くをもっと楽しく、創造的に