Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SwiftUIとGraphQLでプロダクトの継続的な破壊に立ち向かう
Search
たまねぎ
September 19, 2021
Programming
6
2.5k
SwiftUIとGraphQLでプロダクトの継続的な破壊に立ち向かう
iOSDC2021 の発表資料です
たまねぎ
September 19, 2021
Tweet
Share
More Decks by たまねぎ
See All by たまねぎ
[FlutterKaigi2024] Effective Form 〜Flutterによる複雑なフォーム開発の実践〜
chocoyama
1
4.2k
iOSDC2023:聴いて話すiOS 現実世界の「音」との連携
chocoyama
0
300
ハードウェア対応のリアル.pdf
chocoyama
0
70
20分でわかる!速習resultBuilder(iOSDC 2022)
chocoyama
6
2.7k
SwiftUIっぽくした話
chocoyama
1
620
Other Decks in Programming
See All in Programming
テストコード書いてみませんか?
onopon
2
130
선언형 UI에서의 상태관리
l2hyunwoo
0
170
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
4
290
Go の GC の不得意な部分を克服したい
taiyow
3
790
Webエンジニア主体のモバイルチームの 生産性を高く保つためにやったこと
igreenwood
0
340
【re:Growth 2024】 Aurora DSQL をちゃんと話します!
maroon1st
0
780
「とりあえず動く」コードはよい、「読みやすい」コードはもっとよい / Code that 'just works' is good, but code that is 'readable' is even better.
mkmk884
3
470
各クラウドサービスにおける.NETの対応と見解
ymd65536
0
110
htmxって知っていますか?次世代のHTML
hiro_ghap1
0
340
PHPで学ぶプログラミングの教訓 / Lessons in Programming Learned through PHP
nrslib
3
290
数十万行のプロジェクトを Scala 2から3に完全移行した
xuwei_k
0
280
Monixと常駐プログラムの勘どころ / Scalaわいわい勉強会 #4
stoneream
0
280
Featured
See All Featured
Building Applications with DynamoDB
mza
91
6.1k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
111
49k
Designing for Performance
lara
604
68k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.3k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
A Philosophy of Restraint
colly
203
16k
Being A Developer After 40
akosma
87
590k
Building Better People: How to give real-time feedback that sticks.
wjessup
365
19k
A Modern Web Designer's Workflow
chriscoyier
693
190k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Transcript
ɹɹ ©︎ hey, Inc SwiftUIとGraphQLで新規プロダクトの継続的な破壊に立ち向かう ヘイ株式会社 テクノロジー部門 モバイルアプリケーション本部 STORES レジ
iOSエンジニア 横山 拓也(@_chocoyama) iOSDC2021
ɹ ɹ 自己紹介 横山 拓也 Yokoyama Takuya @_chocoyama(Twitter) 2013.04 ヤフー株式会社入社 2019.12 ヘイ株式会社入社
ɹ ɹ CD
ɹ ɹ CD Continuous Delivery? Compact Disk? Creative Director? Career
Development? Cash Dispenser?
ɹ ɹ Continuous Destruction(継続的な破壊) ※ Ωϟονʔͩͱࢥ͚ͬͯͬͨͩͰɺͲ͜ʹఆண͍ͯ͠ͳ͍ݴ༿Ͱ͢
ɹ ɹ アプリケーションの継続的な破壊 改善・変更 (破壊) フィードバック Ұ࡞ͬͯऴΘΓͰͳ͘ɺ ৗʹ࡞ͬͨͷΛյ͠ͳ͕ΒɺΑΓྑ͍ͷΛࢦ͢ • UIの変更
• APIの変更
ɹ ɹ STORES レジ • 実店舗で使うPOSシステムを提供するiPadアプリ • 初期実装から変更がなかった画面はほぼ0 • 「実装→フィードバック→修正」のサイクルを
何度も高速に実行 • リリースまでに少なくとも3回ほど フルリニューアルしている
ɹ ɹ STORES レジの概要
heyが提供するSTORESプラットフォームの中の新しいプロダクト ネットショップと1つになった新しいPOSレジアプリ
ɹ ɹ 主な機能 • お会計 • 決済手段管理 • 精算 •
商品・在庫管理 • ネットショップ連携 ϨδΞϓϦ ϨγʔτϓϦϯλʔ ΩϟογϡυϩΞʔ STORES ܾࡁ όʔίʔυϦʔμʔ
ɹ ɹ 技術スタック • フレームワーク:SwiftUI, Combine • APIクライアント:Apollo-iOS(GraphQL) • SDK:STORES
決済SDK
ɹ ɹ 破壊(変更)への対応
ɹ ɹ 変更に対応していく必要性 変更 Ձ ࣮ ֬ೝ ϦϦʔε ユーザーに価値を与え続けるには、変更は避けられない ࢼߦࡨޡ
ܧଓతͳվળ ϑΟʔυόοΫ ϑΟʔυόοΫ
ɹ ɹ 変更に対応しやすい → ユーザーに価値を届けやすい 変更に対応していく必要性
ɹ ɹ SwiftUI
ɹ ɹ SwiftUIの強み • 宣言的シンタックスで シンプルな記述ができる • Previewを活用して
高速にUIの確認ができる
ɹ ɹ UIKitとの比較 1.レイアウト変更時の修正 2.表示の確認
ɹ ɹ 1. レイアウト変更時の修正 ᶃ DescriptionϥϕϧΛআ ᶄ Ձ֨දࣔͷฒͼͱҐஔมߋ
ɹ ɹ UIKit + AutoLayout 1.不要なViewを削除 2.Viewが消えたことによる不整合を修正 3.位置変更するViewのAutoLayout貼り直し 4.Outlet接続関連のコードを削除 আ
Ҡಈ
ɹ ɹ SwiftUI ① 削除 ② VStackの 外に移動 ③ HStackを削除、
Textの順番を逆に Before After
ɹ ɹ レイアウト変更のしやすさ UIKit+AutoLayout SwiftUI 依存ファイル 多い 少ない 修正ステップ 複雑
単純 安全性 クラッシュの恐れ コンパイラで保証 特有のスキルが必要 素早く安全に対応可能
ɹ ɹ 表示の確認 •「UIの変更→表示確認」のサイクルの速さは、開発効率に直結する •複数の表示パターンがあるUIの場合、特に確認コストがかかる
ɹ ɹ なんか違う… UIKit + AutoLayout •表示が実行時と異なる場合がある •確認はアプリを起動して対象画面に遷移する •1度に1パターンしか確認できない •修正と起動のサイクルを繰り返す可能性がある
このパターン はOK 全部確認 できた! मਖ਼ɾىಈ मਖ਼ɾىಈ मਖ਼ɾىಈ
ɹ ɹ SwiftUI + Xcode Preview •アプリの起動が必要ない •修正内容が即時で確認できる •任意の状態を再現したPreviewの実装を残せる •実装とPreviewを1対多の状態にできる
•(コードだけでも表示イメージがしやすい) 一気に 全部確認 できた! मਖ਼ɾىಈ
ɹ ɹ SwiftUI + Xcode Preview
ɹ ɹ 表示確認のしやすさ UIKit+AutoLayout SwiftUI アプリの起動 必要あり 必要なし パターンごとの確認 毎回起動
1度のPreview実行 継続的な利用 できない できる 高コスト 低コスト
ɹ ɹ デザインシステムに則った 共通UIライブラリを作成 STORES レジでの変更への取り組み •デザインチームが独自のデザインシステムを構築 •アプリデザインはこれをベースに画面設計 変更に耐え得る 仕組みとして
ɹ ɹ デザインシステム = デザイン原則をまとめたスタイルガイドやその実装などの仕組み 以下のような価値を生む • 一貫性のあるIFでユーザー体験を向上 • デザイナーとエンジニア間の共通言語を確立
• 局所最適されたデザインを抑制し、デザイン・開発コストを削減 デザインシステムとは
ɹ ɹ 共通UIコンポーネントの例 ※ Preview༻ͷViewΛ࣮ߦ࣌ʹݺͼग़ͯ͠ɺUIΧλϩάͷΑ͏ͳػೳΛ࡞͍ͬͯ·͢
ɹ ɹ •汎用的に使えるUIを切り出し •→ 切り出し単位はデザインシステムに合わせるだけ •デザイナーとエンジニアの画面構築工程が揃う •→ パーツを組み合わせるだけで画面ができる •アプリ内 SwiftPackageManager
で対象コンポーネントを管理 •→ 依存の切り出し •→ ビルドやPreview実行の高速化 共通UIライブラリの作成 σβΠϯγεςϜʢ໊শඇެ։ʣ σβΠϯγεςϜʢ໊শඇެ։ʣ
ɹ ɹ 実装 σβΠϯ γεςϜ໊ දࣔύλʔϯΛ PreviewͰཏ σβΠϯ γεςϜ໊ σβΠϯ
γεςϜ໊ σβΠϯ γεςϜ໊ σβΠϯ γεςϜ໊ σβΠϯ γεςϜ໊ ※ σβΠϯγεςϜ໊ඇެ։
ɹ ɹ 利用 σβΠϯ γεςϜ σβΠϯ γεςϜ σβΠϯ γεςϜ →
UI作成のコストが激減 σβΠϯ γεςϜ σβΠϯ γεςϜ σβΠϯ γεςϜ σβΠϯ γεςϜ
ɹ ɹ •レイアウトの変更が容易 → 壊しては作るといった繰り返しを気軽にできる •UIの表示確認を効率的にできる → 実装スピードが上がるだけでなく、継続的なメンテナンスにも活用できる
SwiftUIの変更しやすさ UI関連の変更にコストがかからない
ɹ ɹ GraphQL
ɹ ɹ GraphQLとは •API用のクエリ言語 •スキーマによってIFの型が厳密に決まっている
ɹ ɹ REST APIとの比較 GraphQL REST 型付け 強い 弱い エンドポイント
1つ 複数 取得リクエスト Query GET 更新リクエスト Mutation POST/PUT/ PATCH/DELETE
ɹ ɹ GraphQLの強み 1.取得するデータをクライアントが決められる 2.少ないリクエストで複数のリソースにアクセスできる
ɹ ɹ 1. 取得するデータをクライアントが決められる ϦΫΤετ Ϩεϙϯε Ұ୴શσʔλΛऔಘͯ͠ɺඞཁͳͷ͚ͩ͏ → 必要なデータだけ取得する
ɹ ɹ 2. 少ないリクエストで複数のリソースにアクセスできる Φʔμʔৄࡉը໘ アイテム情報 を追加したい
ɹ ɹ REST API の場合 Orders Items APIリクエストが増える Orders itemIds
ɹ ɹ REST API の場合 Orders Items APIリクエストが増える Orders itemIds
追加の通信処理が必要になり、実装が複雑化する OrdersAPIͷ݁ՌΛݩʹɺ ItemsAPIΛୟ͖͢ OrdersAPIΛୟ͚ͩ͘
ɹ ɹ GraphQL の場合 Orders Items APIリクエストが増えない Orders itemIds
ɹ ɹ GraphQL の場合 Orders Items APIリクエストが増えない Orders itemIds 取得したいデータを追加で指定するだけ
ɹ ɹ GraphQL の場合 Orders Items APIリクエストが増えない Orders itemIds 取得できるデータが増えるだけ
ɹ ɹ GraphQL の場合 Orders Items APIリクエストが増えない Orders itemIds 同時に複数のQueryを投げられる
ɹ ɹ STORES レジでの変更への取り組み 1.APIに変更が入ったことの自動検知(独自実装) 2.APIのIFとなるSwiftコードの自動生成(Apollo-iOSの機能を活用)
ɹ ɹ 1. APIに変更が入ったことの自動検知(独自実装) Appエンジニア 想定したデータが取得できません BEエンジニア ドキュメントの更新漏れてました BEエンジニア API完成しました
Appエンジニア APIがエラーになります BEエンジニア 変更の共有忘れてました 人力での変更管理には限界がある ケース1 ケース2
ɹ ɹ 1. APIに変更が入ったことの自動検知(独自実装) 旧スキーマ ファイル 新スキーマ ファイル App BE
旧スキーマ ファイル 新スキーマ ファイル ࠩνΣοΫ 自動でSlackに変更通知 →共有漏れや不正な定義の参照を防ぐ GitHub Bitrise
ɹ ɹ 2. APIのIFとなるSwiftコードの自動生成(Apollo-iOSの機能を利用) スキーマ ファイル BE クエリ ファイル スキーマ
ファイル ੩తղੳ Swiftコードを自動生成 →BEとAppでAPI定義が同期される Local Apollo GitHub
ɹ ɹ •取得したいデータが増えても「追加リクエスト不要」で「IFの型が自動生成される」 → 意図した変更に対応しやすい •API側の変更をシステム的に追従可能なので、人力のコミュニケーションに頼る必要がない →意図していない変更にも対応しやすい データ関連の変更にコストがかからない
GraphQLの変更しやすさ
ɹ ɹ •SwiftUIを利用 → UI関連の変更にコストがかからなくなる •GraphQLを利用 → データ関連の変更にコストがかからなくなる SwiftUIとGraphQLのまとめ ユーザーに価値を届けやすくなる
変更に対応しやすくなる
ɹ ɹ SwiftUI + GraphQL
ɹ ɹ •Viewとセットで、必要なデータをQuery(Fragment)で用意する •UIレイアウトと参照データの定義を1対1で宣言しておく(データ取得も宣言的に行う) •SwiftUIのリアクティブなレンダリング機構と、 Apollo-iOSのコード生成+キャッシュ機構を組み合わせて実現 •レイアウト定義とGraphQL定義で実装がほぼ完結する Fragment Colocation(的なこと)
※ STORES ϨδͰಋೖ͍ͯ͠·ͤΜ
ɹ ɹ サンプル画面
ɹ ɹ 必要な実装コードのすべて SwiftUI GraphQL 1ର1
ɹ ɹ 必要な実装コードのすべて データの 参照 Query Mutation SwiftUI GraphQL 1ର1
ɹ ɹ 実装サンプル(取得データの反映) 1. Queryを発行 →内部キャッシュが変更されると自動呼び出し 2. 再レンダリング 3. 状態に応じた表示
ɹ ɹ 実装サンプル(データの更新) 2. キャッシュの更新を検知 (Queryでオーダーノートを参照→それが更新されると呼び出される) 1. Mutationを発行 (オーダーノートを更新) 3.
再レンダリング 4. オーダーノートの更新
ɹ ɹ 実装サンプル データとUIが同期された状態に
ɹ ɹ PreviewでのAPIのモック Previewでのみ、 カスタムのEnvironmentValueをセット
ɹ ɹ Continuous Destruction(継続的な破壊)
ɹ ɹ •SwiftUI •度重なる変更に対して、UIKitでは実現できないスピードで対応を進められた •OSバージョンの変更に対してはまだ弱い •デザインシステムの実装で開発が効率化したが、デザインシステム自体への変更対応は現状最適化できていない •GraphQL •要件や仕様の変更によって、API実装部分が壊れることがほとんどなかった •自動化の仕組みにより、変更に安全に追従していくことができた •開発フローも含めた最適化なども検討していきたい(スキーマファースト開発など)
振り返り と 今後の展望
ɹ ɹ ありがとうございました! SwiftUIと GraphQL最高!