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

UICollectionViewのAPIを活用してシンプルなコードにリファクタリングする

 UICollectionViewのAPIを活用してシンプルなコードにリファクタリングする

「家族アルバム みてね」のコア機能であるメディアを一覧できる画面のレイアウトをリファクタリングしました。 iOS14以降で使える UICollectionView の API を活用して、レイアウト崩れに強くシンプルなコードに変更する方法を紹介します。

hicka04

March 02, 2023
Tweet

More Decks by hicka04

Other Decks in Programming

Transcript

  1. ©MIXI
    UICollectionViewのAPIを活用して
    シンプルなコードにリファクタリングする
    Vantageスタジオ みてね事業部
    プロダクト開発グループ アプリ開発チーム
    佐藤 光

    View full-size slide

  2. ©MIXI
    自己紹介
    ● 佐藤 光 (@hicka04)
    ● 株式会社MIXI みてね事業部
    ○ 2021/11 中途入社
    ● 二児の父
    ● 「家族アルバム みてね(以下 みてね)」の1ユーザー
    ● 好きなもの
    ○ ラーメン
    ○ ポケモン
    2

    View full-size slide

  3. ©MIXI
    アジェンダ
    ● 「家族アルバム みてね」とは
    ● リファクタリング対象と選んだ理由
    ● リファクタリングの進め方
    ● まとめ
    3

    View full-size slide

  4. ©MIXI
    「家族アルバム みてね」とは

    View full-size slide

  5. ©MIXI
    「家族アルバム みてね」とは
    ● 家族で子供の写真を簡単に共有できるサービス
    ● 「世界中の家族の”こころのインフラ”を作る」
    をミッションに掲げ、現在7言語対応
    ● 利用者数が1,500万人(※)を突破(2023年3月現在)
    ママやパパの「半数」が使うアプリに
    5
    ※iOS・Android™ アプリ登録者数、ブラウザ版登録者数の合計

    View full-size slide

  6. ©MIXI
    リファクタリング対象と選んだ理由

    View full-size slide

  7. ©MIXI
    リファクタリング対象
    ● アルバムタブ
    ● メディアを一覧できる画面
    ● ページの種類
    ○ 月ごとのメディア
    ○ コレクション (1秒動画などのコンテンツ )
    ● 左右スワイプ or 上部のページタップで遷移
    7

    View full-size slide

  8. ©MIXI
    アルバムタブを選んだ理由
    ● 2022/4~ 開発体制をドメインチーム制に変更 (※)
    ○ アルバムの基本機能 (メディアのアップロード/閲覧など)
    ○ メディアを使った商品
    ● アルバムタブに対して手を入れる機会が増えている
    ● 課題: リリース当初から継ぎ足しのコードが多い
    ○ いいものを早く届けるのが困難で、どこかで妥協が発生する
    ■ 修正に多くの工数がかかるのを許容
    ■ 工数がかからないように仕様を調整
    ○ 画面崩れが発生しやすくなっている
    8
    ※2022年版 みてねを支えるプロダクト開発体制

    View full-size slide

  9. ©MIXI
    リファクタリングの進め方

    View full-size slide

  10. ©MIXI
    現状の課題を洗い出し
    ● StoryboardでUI作成
    ○ コードレビューがしやすいコードでのレイアウトを推奨
    ● ViewControllerにロジックが存在
    ○ テストコードが書きづらい
    ● CollectionView
    ○ CollectionViewLayoutを使った地道なFrame計算
    ○ reloadData で全件更新
    ○ セル利用時に非型安全
    ● など…
    10

    View full-size slide

  11. ©MIXI
    CollectionView周りの解決方法の検討
    ● CollectionViewLayoutを使った地道なFrame計算
    ○ → Compositional Layouts (iOS 13 +)
    ● reloadData で全件更新
    ○ → Diffable Data Source (iOS 13 +)
    ● セル利用時に非型安全
    ○ → Cell Registration (iOS 14 +)
    11
    ※2023年3月時点でiOS14以上をサポートしているため、現状使える API限定

    View full-size slide

  12. ©MIXI
    なぜSwiftUIではないのか
    ● みてねでSwiftUIは未導入
    ○ 導入検討中なので、今後活用していきたい
    ● iOS14以上で使えるSwiftUIのAPIでは若干機能不足
    ○ UIだけであればほとんど実装可能そう
    ○ ScrollViewのoffsetを細かく調整する等は難しそうで
    今回のユースケースに合わない
    12

    View full-size slide

  13. ©MIXI
    Compositional Layouts (iOS 13 +)
    ● Section / Group / Item を組み合わせて構造化
    ○ 宣言的にレイアウトを作ることができる
    ● サイズ指定
    ○ 親のN%のサイズ
    ■ fractionalWidth / fractionalHeight
    ○ Self Sizing
    ■ estimated
    ● 位置指定
    ○ Groupの並び horizontal / vertical / custom
    13

    View full-size slide

  14. ©MIXI
    Diffable Data Source (iOS 13 +)
    ● 更新前後のデータ(snapshot)を比較して差分を取り
    必要なセルのみリロードできる
    ● 1つのメソッドでデータ更新完結
    ○ reloadItems / reloadSections / reloadData
    → dataSource.apply(snapshot)
    ● 差分に応じて自動でいい感じのアニメーション
    14

    View full-size slide

  15. ©MIXI
    Cell Registration (iOS 14 +)
    ● セルの利用が型安全
    ● 従来の方法のデメリット: 実行時クラッシュが発生しやすい
    ○ 事前にセルを登録していないと…
    ○ 表示するセルの取得時にtypoすると…
    ● 各々のプロジェクトでextension実装して解決していた
    ○ collectionView.register(CustomCell.self)
    ○ collectionView.dequeue(CustomCell.self, at: indexPath)
    ● 公式のAPIで実現できるようになった
    15

    View full-size slide

  16. ©MIXI
    解決していく
    ● すでにリリース済みのカレンダーUIを例に
    ● 仕様
    ○ 現在のページがわかる
    ○ 表示したい月が増減したときにリロード
    ○ 現在のページが変化したときにリロード
    ○ 1画面内に6セル分入る
    16

    View full-size slide

  17. ©MIXI
    UI & Cell作成
    17
    ● Storyboardで作成されていたため新規で作り直し

    View full-size slide

  18. ©MIXI
    Compositional Layoutsでレイアウト作成
    18

    View full-size slide

  19. ©MIXI
    DataSource作成
    19
    ● セルに対応した型を用意 (Hashable必須)
    ○ ページの種類
    ○ 現在のページかどうか

    View full-size slide

  20. ©MIXI
    DataSource作成
    20

    View full-size slide

  21. ©MIXI
    CollectionViewの初期化
    21
    ● Layout 型と DataSource 型を個別に作っているため
    初期化部分のコードがスッキリ

    View full-size slide

  22. ©MIXI
    UIの更新
    22

    View full-size slide

  23. ©MIXI
    UIの更新
    23
    ● 現在のページを変更するときも reload メソッドを使う

    View full-size slide

  24. ©MIXI
    成果
    ● ほぼ同じ仕様のまま約45%までコードを削減
    ○ +507 -1147
    ● コードの見通しが良くなった
    ○ コード量が少なくなった
    ○ レイアウトの記述が宣言的
    ○ データを更新するメソッドが1つに集約された
    ● 特定の条件下で発生していた画面崩れ解消
    24

    View full-size slide

  25. ©MIXI
    リファクタリングに伴う仕様変更
    ● スワイプでのページ遷移中のアニメーションを変更
    ○ Diffable Data Sourceを使う場合
    UIの状態とデータを一致させた方が実装しやすい
    ○ ピンクのバーではなくOffsetを動かす
    ● チームメンバーやPOに触っていただいた上で許容と判断
    ○ リリース後、この変化をつぶやいている人は見つけられなかった
    25
    Before After

    View full-size slide

  26. ©MIXI
    まとめ

    View full-size slide

  27. ©MIXI
    まとめ
    ● iOS14以上で使えるUICollectionViewのAPIを活用して
    シンプルなコードにリファクタリングする方法を紹介
    ○ コード量削減 & レイアウト崩れに強い
    ○ 現状の仕様を全て満たすのが難しい場合も存在する
    ● メディアを表示するCollectionViewも改善中 →
    ○ 今回紹介できなかったAPIも利用予定
    NSDiffableDataSourceSectionSnapshot
    ● 今後も利用箇所を増やしていって
    シンプル & 画面崩れに強いUIを作っていきたい
    27

    View full-size slide