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のハマりどころとその回避策/ iOSDC_otsuka
Search
Recruit
PRO
September 12, 2022
Technology
5
5.5k
SwiftUIのハマりどころとその回避策/ iOSDC_otsuka
2022/09/11_iOSDC Japan 2022での、大塚の講演資料になります
Recruit
PRO
September 12, 2022
Tweet
Share
More Decks by Recruit
See All by Recruit
明日からできる!技術的負債の返済を加速するための実践ガイド~『ホットペッパービューティー』の事例をもとに~
recruitengineers
PRO
3
100
RECRUIT TECH CONFERENCE 2025 プレイベント【関田】
recruitengineers
PRO
0
21
RECRUIT TECH CONFERENCE 2025 プレイベント【高橋】
recruitengineers
PRO
0
85
RECRUIT TECH CONFERENCE 2025 プレイベント【岡本】
recruitengineers
PRO
2
28
RECRUIT TECH CONFERENCE 2025 プレイベント【恒川】
recruitengineers
PRO
0
23
20250130_『SUUMO』の裏側!第2弾 ~機械学習エンジニアリング編
recruitengineers
PRO
1
950
Asset Centric な データ変換パイプラインの攻略法
recruitengineers
PRO
1
140
Kotlin Multiplatformのポテンシャル
recruitengineers
PRO
2
210
デザイン初め新年会2025_川端_PdM Days2025
recruitengineers
PRO
1
69
Other Decks in Technology
See All in Technology
Developer Summit 2025 [14-D-1] Yuki Hattori
yuhattor
19
5.1k
モノレポ開発のエラー、誰が見る?Datadog で実現する適切なトリアージとエスカレーション
biwashi
6
770
20250208_OpenAIDeepResearchがやばいという話
doradora09
PRO
0
170
君も受託系GISエンジニアにならないか
sudataka
2
370
飲食店予約台帳を支えるインタラクティブ UI 設計と実装
siropaca
6
1.4k
Moved to https://speakerdeck.com/toshihue/presales-engineer-career-bridging-tech-biz-ja
toshihue
2
550
Platform Engineeringは自由のめまい
nwiizo
4
1.9k
PL900試験から学ぶ Power Platform 基礎知識講座
kumikeyy
0
110
10分で紹介するAmazon Bedrock利用時のセキュリティ対策 / 10-minutes introduction to security measures when using Amazon Bedrock
hideakiaoyagi
0
170
Kubernetes x k6 で負荷試験基盤を開発して 負荷試験を民主化した話 / Kubernetes x k6
sansan_randd
2
730
データ資産をシームレスに伝達するためのイベント駆動型アーキテクチャ
kakehashi
PRO
2
230
WAF に頼りすぎない AWS WAF 運用術 meguro sec #1
izzii
0
460
Featured
See All Featured
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.3k
Product Roadmaps are Hard
iamctodd
PRO
50
11k
4 Signs Your Business is Dying
shpigford
182
22k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Code Review Best Practice
trishagee
66
17k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Designing for Performance
lara
604
68k
Adopting Sorbet at Scale
ufuk
74
9.2k
Making the Leap to Tech Lead
cromwellryan
133
9.1k
Building Better People: How to give real-time feedback that sticks.
wjessup
366
19k
How to train your dragon (web standard)
notwaldorf
90
5.8k
A Tale of Four Properties
chriscoyier
158
23k
Transcript
SwiftUIのハマりどころと その回避策 株式会社リクルート ⼤塚 悠貴 2022/9
はじめに © Recruit Co., Ltd. All Rights Reserved 2
3 ⾃⼰紹介 © Recruit Co., Ltd. All Rights Reserved ⼤塚
悠貴 (@moguaiyuki) 所属 経歴 株式会社 リクルート 2020年 4⽉ 株式会社リクルート新卒⼊社 2020年 7⽉ ゼクシィiOS開発 2020年 10⽉ 新規事業プロダクトオーナー 2021年 10⽉ iOS開発
4 本トークのゴール iOS14以上を対象とした『Airインボイス』iOSアプリにおいて SwiftUIを⽤いてさまざまな要件を実現するにあたり、 はまったポイントやそれらをどのように回避したか を共有することで SwiftUIの採⽤の⼀助となる © Recruit Co.,
Ltd. All Rights Reserved
『Airインボイス』とは © Recruit Co., Ltd. All Rights Reserved 5
Airインボイスとは © Recruit Co., Ltd. All Rights Reserved 6 リクルートの事業内容について(主なサービス)
4 選択・意思決定を⽀援する情報サービスを提供し、 「まだ、ここにない、出会い。より速く、シンプルに、もっと近くに」を実現する マッチング&ソリューションSBU HRテクノロジーSBU ⼈材派遣SBU 国内派遣 海外派遣
https://recruit-holdings.com/files/ir/ir_news/upload/20220712_ps_jp.pdf リリース⽇変える Air Business Toolsのいい感じの図持ってきて、 その中のInvoiceって⽴ち位置を説明する https://recruit-holdings.com/files/ir/ir_news/upload/20220712_ps_jp.pdf
8 ※①調査主体︓株式会社リクルート②調査実施機関︓株式会社インテージ(2021年11⽉22⽇時点) ③⽐較条件︓銀⾏133⾏(*)の通常時の他⾏宛の 振込⼿数料で⽐較(条件付きの振込⼿数料は考慮せず) (*)⾦融庁、免許・許可・登録等を受けている業者⼀覧のうち、預⾦取扱等⾦融機関で銀⾏として登録されているもの。外国銀⾏⽀店を除く133⾏
9 『Airインボイス』 とは
『Airインボイス』 における SwiftUI採⽤の背景とその効果 © Recruit Co., Ltd. All Rights Reserved
10
11 SwiftUI採⽤の背景とその効果 © Recruit Co., Ltd. All Rights Reserved •
新規開発 (既存コードなし) • SwiftUIが安定してきたiOS14以上をサポート • 社内でもスタディサプリが既にSwiftUI採⽤済み SwiftUIの採⽤背景 • UIの実装速度が向上 • レイアウトの記述がシンプル • コンポーネントの再利⽤が容易 • Previewで⾼速にUI変更確認 • Storyboardやxibと⽐較してレビューが容易 …など、メリットを沢⼭感じることができた SwiftUI採⽤による効果
ハマりどころとその回避策 © Recruit Co., Ltd. All Rights Reserved 12 ※本スライドはiOS14,
15をサポート対象とする前提のコードとなっています。
13 様々な要件 1. DeepLink 2. 1画⾯で複数種類のアラートダイアログ 3. 1画⾯から複数の画⾯へのモーダル遷移 4. カスタムダイアログ
/ トースト / チュートリアル © Recruit Co., Ltd. All Rights Reserved
14 様々な要件 1. DeepLink 2. 1画⾯で複数種類のアラートダイアログ 3. 1画⾯から複数の画⾯へのモーダル遷移 4. カスタムダイアログ
/ トースト / チュートリアル © Recruit Co., Ltd. All Rights Reserved
15 SwiftUIでの基本的なpush遷移 © Recruit Co., Ltd. All Rights Reserved ユーザーがNavigationLinkを
タップすることで遷移 Deep linkのようなプログラム的に遷移する要件には使えない
16 プログラムで遷移を制御する © Recruit Co., Ltd. All Rights Reserved ※iOS16以上ではinit(value:
label:)を使⽤ 空(EmptyView)のNavigationLinkを Backgroundに仕込む destinationの値が”pageA”になった時 遷移を発⽕する
17 アプリのどこからでも遷移を制御できるようにする © Recruit Co., Ltd. All Rights Reserved @EnvironmentObjectにViewRouterを格納し、
アプリのどこからでも遷移を制御できるようにする 各画⾯の画⾯遷移を制御するViewRouterをまとめた ObservableObject 遷移先を定義 viewRouter.firstPageViewRouter.destinationの 値を変更することで遷移を発⽕する
18 DeepLinkを実装する © Recruit Co., Ltd. All Rights Reserved .onOpenURLでURLスキームを
受け取り、ViewRouterを⽤いて 画⾯遷移を発⽕する
ハマりポイント① © Recruit Co., Ltd. All Rights Reserved 19
20 このコードどこに問題があるでしょうか︖
21 このコードどこに問題があるでしょうか︖ NavigationLinkが2つあることが問題 ※ iOS15は問題なし
22 iOS14&NavigationLink 2つのみの場合挙動が不安定 © Recruit Co., Ltd. All Rights Reserved
ページ3まで遷移すると 勝⼿にページ1に戻る ページ1 ページ2 ページ3 遷移 遷移 ※デモ動画
23 iOS14系&NavigationLink 2つのみの場合挙動が不安定 © Recruit Co., Ltd. All Rights Reserved
遷移直後に勝⼿に戻る問題の報告 NavigationLinkが 2つの場合のみ発⽣ https://developer.apple.com/forums/thread/677333 https://forums.swift.org/t/14-5-beta3-navigationlink-unexpected-pop/45279
24 回避策 © Recruit Co., Ltd. All Rights Reserved ダミーのNavigationLinkをいれて
NavigationLinkの数を3つにする
ハマりポイント② © Recruit Co., Ltd. All Rights Reserved 25
26 このコードどこに問題があるでしょうか︖ © Recruit Co., Ltd. All Rights Reserved 特定のボタンがタップされた際に、そのボタンに応じた値を遷移先に渡したい
ボタンがタップされたら pageAIdを代⼊する pageAIdがあるときのみ、 NavigationLinkを⽣成する
27 このコードどこに問題があるでしょうか︖ © Recruit Co., Ltd. All Rights Reserved NavigationLinkを⽣成した直後に
遷移を発⽕していることが問題
28 if letでNavigationLinkが⽣成された直後に遷移すると 遷移アニメーションがなくなる(iOS14&15) © Recruit Co., Ltd. All Rights
Reserved 期待動作 実際 ※デモ動画 ※デモ動画
29 回避策? © Recruit Co., Ltd. All Rights Reserved この遷移を使う時は必ずpageAIdがnon-null
強制アンラップしてみる︖
30 回避策? © Recruit Co., Ltd. All Rights Reserved この遷移を使う時は必ずpageAIdがnon-null
強制アンラップしてみる︖ Viewを⽣成した時点ではnullなのでもちろんダメ
31 回避策 © Recruit Co., Ltd. All Rights Reserved destinationの中でif
letを使⽤する
32 様々な要件 1. DeepLink 2. 1画⾯で複数種類のアラートダイアログ 3. 1画⾯から複数の画⾯へのモーダル遷移 4. カスタムダイアログ
/ トースト / チュートリアル © Recruit Co., Ltd. All Rights Reserved
33 1画⾯で複数種類のアラートダイアログを表出する © Recruit Co., Ltd. All Rights Reserved
ハマりポイント③ © Recruit Co., Ltd. All Rights Reserved 34
35 このコードのどこに問題があるでしょうか︖ © Recruit Co., Ltd. All Rights Reserved
36 このコードのどこに問題があるでしょうか︖ © Recruit Co., Ltd. All Rights Reserved 1つのViewに対して複数の.alertを
利⽤していることが問題 ※ iOS14 15共に問題あり
37 1つのViewに対して1つしか.alertは定義できない © Recruit Co., Ltd. All Rights Reserved 2つ⽬の.alertのみ有効
38 2つ⽬のアラートしか表⽰されない © Recruit Co., Ltd. All Rights Reserved アラート1は表⽰されない
アラート2は表⽰される
39 回避策 © Recruit Co., Ltd. All Rights Reserved 1つの.alertの中で
複数パターン出し分ける アラートのパターンを定義しておく
40 様々な要件 1. DeepLink 2. 1画⾯で複数種類のアラートダイアログ 3. 1画⾯から複数の画⾯へのモーダル遷移 4. カスタムダイアログ
/ トースト / チュートリアル © Recruit Co., Ltd. All Rights Reserved
41 ある画⾯から⼆つの画⾯にモーダル遷移したい © Recruit Co., Ltd. All Rights Reserved
ハマりポイント④ © Recruit Co., Ltd. All Rights Reserved 42
43 このコードのどこに問題があるでしょうか︖ © Recruit Co., Ltd. All Rights Reserved
44 このコードのどこに問題があるでしょうか︖ © Recruit Co., Ltd. All Rights Reserved 1つのViewに対して
2つの.fullScreenCoverを 利⽤していることが問題 ※iOS14.5以上は問題ない
45 iOS14.5未満では.fullScreenCoverは 1つのViewに対して2つ使えない © Recruit Co., Ltd. All Rights Reserved
ページ1に遷移しない ページ2には遷移する
46 回避策(?) © Recruit Co., Ltd. All Rights Reserved 1つのEmptyViewに対して1つの
.fullScreenCoverを定義する
47 iOS14(iOS14.5含む)で正常に動作する © Recruit Co., Ltd. All Rights Reserved ページ1に遷移
ページ2に遷移
48 iOS15でどちらも動かない © Recruit Co., Ltd. All Rights Reserved ページ1に遷移しない
ページ2に遷移しない
49 苦⾁の回避策 © Recruit Co., Ltd. All Rights Reserved iOS14.5未満かどうかで
実装を変更 条件によってmodifierを適⽤する modifier
50 様々な要件 1. DeepLink 2. 1画⾯で複数種類のアラートダイアログ 3. 1画⾯から複数の画⾯へのモーダル遷移 4. カスタムダイアログ
/ トースト / チュートリアル © Recruit Co., Ltd. All Rights Reserved
51 TabViewやNavigationViewを含む 全画⾯に対してカスタムUIを被せる © Recruit Co., Ltd. All Rights Reserved
ハマりポイント⑤ © Recruit Co., Ltd. All Rights Reserved 52
53 NavigationViewやTabViewの⼦Viewに対して カスタムダイアログを表⽰すると全画⾯に被さらない © Recruit Co., Ltd. All Rights Reserved
⼦Viewでダイアログを 管理する
54 NavigationViewに対してカスタムダイアログを表⽰すれば 実現可能だが、ダイアログ等は各タブや遷移先で管理したい © Recruit Co., Ltd. All Rights Reserved
NavigationViewに対して カスタムダイアログを宣⾔する TabViewA内でshowDialog変数を Trueにしてダイアログを表⽰する
55 UIWindowを活⽤する © Recruit Co., Ltd. All Rights Reserved 全画⾯に表⽰したいカスタムUIは全て
UIWindowを⽤いて実装
56 UIWindowを活⽤する © Recruit Co., Ltd. All Rights Reserved どのViewからでも全画⾯の
ダイアログが表⽰可能
57 UIWindowを利⽤することで、カスタムダイアログ の上にさらにチュートリアルを出すことも © Recruit Co., Ltd. All Rights Reserved
チュートリアルとカスタムダイアログを別々の Windowで管理しているため、簡単に実現可能
まとめ © Recruit Co., Ltd. All Rights Reserved 58
59 まとめ © Recruit Co., Ltd. All Rights Reserved ①iOS14系のNavigationLinkの挙動には気をつける
②If let でNavigationLinkは⽣成しない ③.alertは1つのViewに対して1つのみ ④.fullScreenCoverはiOS14.5未満に対しては1つのViewに1つのみ ⑤全画⾯にまたがるカスタムダイアログ等はUIWindowの活⽤も⼀つの選択肢 ハマりポイント
60 まとめ © Recruit Co., Ltd. All Rights Reserved UIの実装速度が向上
l レイアウトの記述がシンプル l コンポーネントの再利⽤が容易 l Previewで⾼速にUI変更確認 l Storyboardやxibと⽐較してレビューが容易 ….など、メリットを沢⼭感じることができた SwiftUIはハマりポイントもあったが、総じて採⽤してよかった 採⽤してよかった理由