$30 off During Our Annual Pro Sale. View Details »

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

ああうえ
September 17, 2021
4.7k

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

ああうえ

September 17, 2021
Tweet

Transcript

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

    View Slide

  2. 2
    自己紹介
    ● ああうえ / @_kwzr_
    ● 仕事: pixiv Sketchの開発
    ● 個人: Pose Arch 15万DL🎉
    ああうえ
    モバイルアプリエンジニア

    View Slide

  3. 4
    アジェンダ
    1. デザインシステムとは
    2. Kotlin Multiplatform Projectを使ったデザイントークンの実装
    3. 画像・色アセットの作成
    4. UIKit・SwiftUIでのコンポーネント作成

    View Slide

  4. 5
    デザインシステムとは?
    以下をまとめたもの

    スタイルガイド

    UIライブラリ

    スタイルガイドとUIライブラリを繋ぐ、ルール・ツール群

    View Slide

  5. 6
    スタイルガイド

    デザインに関する原則がまとまったドキュメント

    ボタンの見た目など、画面ごとに違ってユーザーを混乱させない

    統一したUIを提供することで、ブランディングを向上させる

    View Slide

  6. 7
    UIライブラリ

    UIの実装をまとめたもの

    コード量・メンテナンスコストを減らし、生産性を上げる。誰が実装
    しても同じものを作れるようにするのが目的

    以下の要素で構成される

    デザイントークン

    Spacing, Typography, Border Radius, Color Palette,
    Icon, Animation…

    コンポーネント

    ボタン、スイッチ、...

    View Slide

  7. 8
    ルール・ツール群

    どこにリソースを置くか?どう更新するか?などの運用ルール

    画像の書き出し、各OSで使えるように変換するスクリプトなど

    ルールを自動化するためのCI

    View Slide

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

    View Slide

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

    View Slide

  10. 11
    状況

    4サービス、8アプリがデザインシステムに対応する可能性

    歴史が長いアプリが多いのでまだまだ先は長い

    各アプリの実装状況

    iOS

    Interface Builderで独自のCustom Classを設定

    View Controllerで逐一スタイルを設定

    SwiftUI

    Android

    独自のViewを定義

    styles.xmlに定義されたスタイルを適用

    View Slide

  11. 12
    Webフロントでの導入

    2019年ごろからデザインシステムの整備・導入が進められている

    Tailwind CSSの思想で作られたユーティリティファーストなデザイン
    システム

    https://inside.pixiv.blog/2021/07/01/151500

    View Slide

  12. 13
    Webフロントでの導入

    以下のようなレイヤーで構成

    Constants(デザイントークン)

    Spacing, Typography, Border Radius, Palette, Icons...

    Utilities

    Tailwind CSSを拡張したCSS層

    これによって、ReactでもVueでも使用可能

    Components

    Buttonなどのコンポーネント

    .bg-background1
    .typography-12
    const background1 = “#fff”
    const typography12 = {
    fontSize: 12,
    lineHeight: 20
    }
    Components
    Utilities
    Constants

    View Slide

  13. 14
    アプリにも導入する

    Webフロントで導入が進められているデザインシステムを
    iOS・Androidにもどのように導入するか?

    異なるプラットフォーム間で、どうやってスタイルの一貫性を保って
    運用していくか?

    View Slide

  14. 15
    Single Source of Truth

    信頼できる唯一の情報源

    どれが最新か、信頼性のあるデータなのか考えずに使えるよう
    にする

    参照する情報が複数あると、どれを変更したり参照したりすればいい
    かわからない。参照元を一つにする

    マルチプラットフォーム、複数サービスへの適用を考えて、一つの情
    報源を参照できるように、運用ルール、CIなどを設定する

    View Slide

  15. 16
    デザインシステムの構成
    library-ios library-android
    ● デザイントークン
    ● コンポーネント
    ● アセット
    ● 各プラットフォーム向けツール
    など
    image: Flaticon.com

    View Slide

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

    View Slide

  17. 18
    デザイントークンとは

    Single Source of Truthを実現するためにSalesforceが提唱

    デザインに関する以下のような定数を指す

    Spacing

    Border Radius

    Typography

    Color Palette



    上記のような定数をYAML・JSONなどで定義しておき、
    Web・iOS・Android各プラットフォームのコードに変換する

    View Slide

  18. 19
    デザイントークンの実装
    ● Web・iOS・Androidで最初から共通化するのであれば、以下のようなデザイ
    ントークン実装を採用するのも良い
    ● https://github.com/salesforce-ux/theo
    ● https://github.com/amzn/style-dictionary
    ● https://github.com/diez/diez

    View Slide

  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

    View Slide

  20. 21
    MPPの簡単な使用例

    プロジェクトを作ると、androidMain, commonMain, iosMainのよう
    に各プラットフォーム用のパッケージが生成される

    共通のコードはcommonMain / commonTestに置かれる

    View Slide

  21. 22
    各プラットフォームのコードを書く
    ● expect, actual宣言で各プラットフォーム向けのコードを書ける

    View Slide

  22. 23
    MPPを使うメリット

    Kotlinによって、より高い表現力で実装できる

    例えば、定義の再利用

    YAMLやJSONなどを各プラットフォームで読まなくて良い

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  26. 27
    Multiplatform Libraryを作る

    MPPで作ったものは各OSのライブラリとして配布可能

    IntelliJ IDEAにはMultiplatform Libraryのテンプレートがあるので
    これを使うのがおすすめ

    View Slide

  27. 28
    Swift Packageで配布する

    multiplatform-swiftpackage Gradleプラグインを使用する

    outputDirectoryをリポジトリのrootDirに設定しておくと、GitHub
    経由などでSwift Packageを取得できる
    build.gradle.kts 生成されるファイル

    View Slide

  28. 29
    Mavenで配布

    maven-publish Gradleプラグインを使用してライブラリを配布する

    iOSのartifactsも生成されるが、取得する際は必要なのものだけが取
    得されるので、気にしなくて良いのがGood
    build.gradle

    View Slide

  29. library-ios library-android
    library-mobile-foundation
    ● デザイントークン
    ● モバイル共通の定義
    ● コンポーネント
    ● アセット
    ● 各プラットフォーム向けツール
    30
    アセット
    image: Flaticon.com

    View Slide

  30. 31
    アセットの配布

    MPPではAssetを扱えない🥺

    iOSは画像や色をInterface Builder上から使えるようにしたり、ダー
    クモード対応のために、Asset Catalog対応したい

    library-iosの層でAsset Catalogを作る

    既存のデザイントークンライブラリでも完全に対応されている
    ものがなさそう

    Androidも同様に、library-androidの層でcolors.xmlや
    VectorDrawableを配置してあげる

    View Slide

  31. 32
    アセットの変換

    iOS

    Asset Catalogへの変換を地道にやる

    iOS 12以下への対応

    SVG形式の利用はiOS 13+

    PDF形式で吐き出す必要がある

    Android

    SVG→VectorDrawableに変換する

    Android Studioのソースコードを参照

    View Slide

  32. 33
    アイコンの自動更新

    Figmaのアイコンが更新されたらコード側にも反映されてほしい

    Figma APIを叩いてCIでアイコンを自動更新する

    特定のページにある特定の命名規則のアイコンを取り出し、PR
    を作成する

    1日ごとなど定期実行する

    https://inside.pixiv.blog/2021/01/22/170000

    View Slide

  33. library-ios library-android
    library-mobile-foundation
    ● デザイントークン
    ● モバイル共通の定義
    ● コンポーネント
    ● アセット
    ● 各プラットフォーム向けツール
    34
    コンポーネント
    image: Flaticon.com

    View Slide

  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

    View Slide

  35. 36
    コンポーネントの実装(UIKit)

    デザインシステム自体の実装は、SwiftUIの方が楽...

    デザインシステムを導入するためSwiftUIを必須化するのは非現実的

    引き続き、UIKitでも開発できるようにする

    Interface Builder上でスタイルが設定できるようにする

    View Slide

  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はまだしばらく切れないので...

    View Slide

  37. 38
    コンポーネントの実装(SwiftUI)

    スタイルを変えるのに、独自にViewを継承して実装はしない

    View Slide

  38. 39
    コンポーネントの実装(SwiftUI)

    Modifierを実装し、extensionでスタイルを利用できるように

    デザインシステムの定義ということがわかる

    補完が効いて便利

    View Slide

  39. 40
    コンポーネントの実装(SwiftUI)

    TypographyやBorder Radiusなどもextension化

    デザインシステムの定義ということがわかる

    補完が効いて便利

    .foregroundColor(PixivColor.background01) みたいな誤用防ぐ

    View Slide

  40. 42
    コンポーネントの実装(Android)

    Androidも、現状の実装と将来的にどうしたいかを考えて実装

    Android View

    viewInflaterClassを使った、既存のXMLの置き換え

    TextView→MaterialTextViewのように自動的に置き換えること
    ができる

    Jetpack Compose

    まだ検討中

    SwiftUIと似たような実装になりそう

    View Slide

  41. 43
    まとめ

    デザインシステムがあることによって、サービス・アプリのブラン
    ディングや開発体験に大きく影響

    Single Source of Truthを実現するために、デザイントークンの実装
    が重要

    style-dictionary、diezなど既存の実装を使うか、MPPを使うか
    プロダクトによって見極める

    色や画像リソースの変換は現状ではがんばるしかない

    UIKit・SwiftUIでのコンポーネント設計方針を話した

    View Slide

  42. 45
    参考文献

    Design Systems ―デジタルプロダクトのためのデザインシステム実
    践ガイド Alla Kholmatova(著), 佐藤伸哉(翻訳)

    Kotlin Multiplatform | Kotlin

    View Slide