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

iOS・Androidで使える デザインシステムをどう実装するか

04220a462f57cb4551c9659e94c71354?s=47 kwzr
September 17, 2021
1.4k

iOS・Androidで使える デザインシステムをどう実装するか

04220a462f57cb4551c9659e94c71354?s=128

kwzr

September 17, 2021
Tweet

Transcript

  1. iOS・Androidで使える デザインシステムをどう実装するか pixiv Inc. ああうえ 2021.9.17 19:50〜 iOSDC Track C

  2. 2 自己紹介 • ああうえ / @_kwzr_ • 仕事: pixiv Sketchの開発

    • 個人: Pose Arch 15万DL🎉 ああうえ モバイルアプリエンジニア
  3. 4 アジェンダ 1. デザインシステムとは 2. Kotlin Multiplatform Projectを使ったデザイントークンの実装 3. 画像・色アセットの作成

    4. UIKit・SwiftUIでのコンポーネント作成
  4. 5 デザインシステムとは? 以下をまとめたもの • スタイルガイド • UIライブラリ • スタイルガイドとUIライブラリを繋ぐ、ルール・ツール群

  5. 6 スタイルガイド • デザインに関する原則がまとまったドキュメント • ボタンの見た目など、画面ごとに違ってユーザーを混乱させない • 統一したUIを提供することで、ブランディングを向上させる

  6. 7 UIライブラリ • UIの実装をまとめたもの • コード量・メンテナンスコストを減らし、生産性を上げる。誰が実装 しても同じものを作れるようにするのが目的 • 以下の要素で構成される ◦

    デザイントークン ▪ Spacing, Typography, Border Radius, Color Palette, Icon, Animation… ◦ コンポーネント ▪ ボタン、スイッチ、...
  7. 8 ルール・ツール群 • どこにリソースを置くか?どう更新するか?などの運用ルール • 画像の書き出し、各OSで使えるように変換するスクリプトなど • ルールを自動化するためのCI

  8. 9 弊社の状況 6サービス、12のアプリ

  9. 10 弊社の状況 6サービス、12のアプリ Unity製 考慮 しない

  10. 11 状況 • 4サービス、8アプリがデザインシステムに対応する可能性 ◦ 歴史が長いアプリが多いのでまだまだ先は長い • 各アプリの実装状況 ◦ iOS

    ▪ Interface Builderで独自のCustom Classを設定 ▪ View Controllerで逐一スタイルを設定 ▪ SwiftUI ◦ Android ▪ 独自のViewを定義 ▪ styles.xmlに定義されたスタイルを適用
  11. 12 Webフロントでの導入 • 2019年ごろからデザインシステムの整備・導入が進められている • Tailwind CSSの思想で作られたユーティリティファーストなデザイン システム ◦ https://inside.pixiv.blog/2021/07/01/151500

  12. 13 Webフロントでの導入 • 以下のようなレイヤーで構成 • Constants(デザイントークン) ◦ Spacing, Typography, Border

    Radius, Palette, Icons... • Utilities ◦ Tailwind CSSを拡張したCSS層 ◦ これによって、ReactでもVueでも使用可能 • Components ◦ Buttonなどのコンポーネント <Button> .bg-background1 .typography-12 const background1 = “#fff” const typography12 = { fontSize: 12, lineHeight: 20 } Components Utilities Constants
  13. 14 アプリにも導入する • Webフロントで導入が進められているデザインシステムを iOS・Androidにもどのように導入するか? • 異なるプラットフォーム間で、どうやってスタイルの一貫性を保って 運用していくか?

  14. 15 Single Source of Truth • 信頼できる唯一の情報源 ◦ どれが最新か、信頼性のあるデータなのか考えずに使えるよう にする

    • 参照する情報が複数あると、どれを変更したり参照したりすればいい かわからない。参照元を一つにする • マルチプラットフォーム、複数サービスへの適用を考えて、一つの情 報源を参照できるように、運用ルール、CIなどを設定する
  15. 16 デザインシステムの構成 library-ios library-android • デザイントークン • コンポーネント • アセット

    • 各プラットフォーム向けツール など image: Flaticon.com
  16. 17 デザインシステムの構成 library-ios library-android library-mobile-foundation • デザイントークン • モバイル共通の定義 •

    コンポーネント • アセット • 各プラットフォーム向けツール image: Flaticon.com
  17. 18 デザイントークンとは • Single Source of Truthを実現するためにSalesforceが提唱 • デザインに関する以下のような定数を指す ◦

    Spacing ◦ Border Radius ◦ Typography ◦ Color Palette ◦ … • 上記のような定数をYAML・JSONなどで定義しておき、 Web・iOS・Android各プラットフォームのコードに変換する
  18. 19 デザイントークンの実装 • Web・iOS・Androidで最初から共通化するのであれば、以下のようなデザイ ントークン実装を採用するのも良い • https://github.com/salesforce-ux/theo • https://github.com/amzn/style-dictionary •

    https://github.com/diez/diez
  19. 20 MPPを使ったデザイントークン実装 • ピクシブで現在進めているデザイントークン実装 • Kotlin Multiplatform Project(MPP)をデザイントークン実装に使う • MPPとは?

    ◦ KotlinはMultiplatform Programmingを主要な利点として上げ ている ◦ Kotlinで書かれたコードをKotlin/JVM, Kotlin/Native, Kotlin/JSのネイティブコードに変換。マルチプラットフォーム での開発を可能にする ◦ 2021年9月1日現在はAlpha段階 ◦ Alpha段階: use at your own risk, expect migration issues
  20. 21 MPPの簡単な使用例 • プロジェクトを作ると、androidMain, commonMain, iosMainのよう に各プラットフォーム用のパッケージが生成される • 共通のコードはcommonMain /

    commonTestに置かれる
  21. 22 各プラットフォームのコードを書く • expect, actual宣言で各プラットフォーム向けのコードを書ける

  22. 23 MPPを使うメリット • Kotlinによって、より高い表現力で実装できる ◦ 例えば、定義の再利用 • YAMLやJSONなどを各プラットフォームで読まなくて良い

  23. 24 ピクシブでの実装 • ピクシブでは既存の実装を生かすため、WebのTypeScript実装を JSON Schema化してKotlinの型に変換したものを配置している • なので、前述したメリットは実はほとんどない...が ◦ MPPを最初から選択できる場合は大きなメリットとなりそう

    ◦ アプリでのみ存在する定義を吸収する層にはなっている
  24. 25 ライブラリとして配布 library-ios library-android library-mobile-foundation • デザイントークン • モバイル共通の定義 •

    コンポーネント • アセット • 各プラットフォーム向けツール image: Flaticon.com
  25. 26 ライブラリとして配布 library-ios library-android library-mobile-foundation • デザイントークン • モバイル共通の定義 •

    コンポーネント • アセット • 各プラットフォーム向けツール image: Flaticon.com
  26. 27 Multiplatform Libraryを作る • MPPで作ったものは各OSのライブラリとして配布可能 • IntelliJ IDEAにはMultiplatform Libraryのテンプレートがあるので これを使うのがおすすめ

  27. 28 Swift Packageで配布する • multiplatform-swiftpackage Gradleプラグインを使用する • outputDirectoryをリポジトリのrootDirに設定しておくと、GitHub 経由などでSwift Packageを取得できる

    build.gradle.kts 生成されるファイル
  28. 29 Mavenで配布 • maven-publish Gradleプラグインを使用してライブラリを配布する • iOSのartifactsも生成されるが、取得する際は必要なのものだけが取 得されるので、気にしなくて良いのがGood build.gradle

  29. library-ios library-android library-mobile-foundation • デザイントークン • モバイル共通の定義 • コンポーネント •

    アセット • 各プラットフォーム向けツール 30 アセット image: Flaticon.com
  30. 31 アセットの配布 • MPPではAssetを扱えない🥺 • iOSは画像や色をInterface Builder上から使えるようにしたり、ダー クモード対応のために、Asset Catalog対応したい ◦

    library-iosの層でAsset Catalogを作る ◦ 既存のデザイントークンライブラリでも完全に対応されている ものがなさそう • Androidも同様に、library-androidの層でcolors.xmlや VectorDrawableを配置してあげる
  31. 32 アセットの変換 • iOS ◦ Asset Catalogへの変換を地道にやる ◦ iOS 12以下への対応

    ▪ SVG形式の利用はiOS 13+ ▪ PDF形式で吐き出す必要がある • Android ◦ SVG→VectorDrawableに変換する ◦ Android Studioのソースコードを参照
  32. 33 アイコンの自動更新 • Figmaのアイコンが更新されたらコード側にも反映されてほしい • Figma APIを叩いてCIでアイコンを自動更新する ◦ 特定のページにある特定の命名規則のアイコンを取り出し、PR を作成する

    ◦ 1日ごとなど定期実行する ◦ https://inside.pixiv.blog/2021/01/22/170000
  33. library-ios library-android library-mobile-foundation • デザイントークン • モバイル共通の定義 • コンポーネント •

    アセット • 各プラットフォーム向けツール 34 コンポーネント image: Flaticon.com
  34. 35 コンポーネントの実装 • library-ios, library-androidにそれぞれ実装 • 各OS、パラダイムごとに実装を用意 ◦ UIKit・SwiftUI・Android View・Jetpack

    Compose ◦ 性質上仕方ない。将来的にはアプリ側の実装を揃えていく • FlutterのAdd-to-appは? ◦ 共通のコンポーネントを実装して、iOS・Androidから使用可 ◦ 各プラットフォームでの体験を大切にするため使わない ▪ MPPの思想でもUIは各OSのネイティブで実装することを勧 めている ▪ https://kotlinlang.org/docs/mobile/architect-kmm-ap p.html
  35. 36 コンポーネントの実装(UIKit) • デザインシステム自体の実装は、SwiftUIの方が楽... • デザインシステムを導入するためSwiftUIを必須化するのは非現実的 ◦ 引き続き、UIKitでも開発できるようにする • Interface

    Builder上でスタイルが設定できるようにする
  36. 37 コンポーネントの実装(UIKit) • @IBInspectableにenumが使えない問題 ◦ ボタンのスタイルを設定するときにどうするか • 2つの方法 ◦ 1スタイル=1Custom

    Classで実装する←こちらを採用 ▪ Figmaの定義と同じクラス名にする(prefixは除く) ◦ #if TARGET_INTERFACE_BUILDERを使って、コード上からは enum、Interface BuilderからはIntやStringで設定する方法 ▪ Int: 欠番などの扱い、Figma上のものと揃えるのが難しい ▪ String: 入力補完ができない ▪ IBLinterなどでLintが難しい • UIButton.Configuration(iOS 15+)は考えない ◦ iOS 14はまだしばらく切れないので...
  37. 38 コンポーネントの実装(SwiftUI) • スタイルを変えるのに、独自にViewを継承して実装はしない

  38. 39 コンポーネントの実装(SwiftUI) • Modifierを実装し、extensionでスタイルを利用できるように ◦ デザインシステムの定義ということがわかる ◦ 補完が効いて便利

  39. 40 コンポーネントの実装(SwiftUI) • TypographyやBorder Radiusなどもextension化 ◦ デザインシステムの定義ということがわかる ◦ 補完が効いて便利 ◦

    .foregroundColor(PixivColor.background01) みたいな誤用防ぐ
  40. 42 コンポーネントの実装(Android) • Androidも、現状の実装と将来的にどうしたいかを考えて実装 • Android View ◦ viewInflaterClassを使った、既存のXMLの置き換え ◦

    TextView→MaterialTextViewのように自動的に置き換えること ができる • Jetpack Compose ◦ まだ検討中 ◦ SwiftUIと似たような実装になりそう
  41. 43 まとめ • デザインシステムがあることによって、サービス・アプリのブラン ディングや開発体験に大きく影響 • Single Source of Truthを実現するために、デザイントークンの実装

    が重要 ◦ style-dictionary、diezなど既存の実装を使うか、MPPを使うか プロダクトによって見極める • 色や画像リソースの変換は現状ではがんばるしかない • UIKit・SwiftUIでのコンポーネント設計方針を話した
  42. 45 参考文献 • Design Systems ―デジタルプロダクトのためのデザインシステム実 践ガイド Alla Kholmatova(著), 佐藤伸哉(翻訳)

    • Kotlin Multiplatform | Kotlin