Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SwiftUIに適した新アーキテクチャの導入に挑む

Ryu-nakayama
September 03, 2023

 SwiftUIに適した新アーキテクチャの導入に挑む

iOSDC2023 Day2の発表資料です

Ryu-nakayama

September 03, 2023
Tweet

More Decks by Ryu-nakayama

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  6. 事業概要
    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を突破
    ● 電話やメールから効率的なチャットへ、ビジネスコミュニケーションの変化を加速させプラットフォーム化を目指す

    View Slide

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

    View Slide

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

    View Slide

  9. 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の新機能
    長い歴史と
    共に増える
    技術的負債

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  26. SVVSとは

    View Slide

  27. SVVSとは
    27
    Store
    View
    View
    State

    View Slide

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


    View Slide

  29. SVVSとは
    29
    Store
    View
    View
    State
    画面


    View Slide

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


    View Slide

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

    View Slide

  32. 32
    Store

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  37. 37
    View
    State

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  42. 42
    View

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  47. 各コンポーネントの関係

    View Slide

  48. 依存関係

    View Slide

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


    View Slide

  50. データの流れ

    View Slide

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

    View Slide

  52. SVVS 3つの特徴

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  58. まとめ
    58

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide