2022/09/11_iOSDC Japan 2022での、大塚の講演資料になります
SwiftUIのハマりどころとその回避策株式会社リクルート⼤塚 悠貴2022/9
View Slide
はじめに© Recruit Co., Ltd. All Rights Reserved2
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 Reserved5
Airインボイスとは© Recruit Co., Ltd. All Rights Reserved6リクルートの事業内容について(主なサービス)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 Reserved10
11SwiftUI採⽤の背景とその効果© Recruit Co., Ltd. All Rights Reserved• 新規開発 (既存コードなし)• SwiftUIが安定してきたiOS14以上をサポート• 社内でもスタディサプリが既にSwiftUI採⽤済みSwiftUIの採⽤背景• UIの実装速度が向上• レイアウトの記述がシンプル• コンポーネントの再利⽤が容易• Previewで⾼速にUI変更確認• Storyboardやxibと⽐較してレビューが容易…など、メリットを沢⼭感じることができたSwiftUI採⽤による効果
ハマりどころとその回避策© Recruit Co., Ltd. All Rights Reserved12※本スライドはiOS14, 15をサポート対象とする前提のコードとなっています。
13様々な要件1. DeepLink2. 1画⾯で複数種類のアラートダイアログ3. 1画⾯から複数の画⾯へのモーダル遷移4. カスタムダイアログ / トースト / チュートリアル© Recruit Co., Ltd. All Rights Reserved
14様々な要件1. DeepLink2. 1画⾯で複数種類のアラートダイアログ3. 1画⾯から複数の画⾯へのモーダル遷移4. カスタムダイアログ / トースト / チュートリアル© Recruit Co., Ltd. All Rights Reserved
15SwiftUIでの基本的な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の値を変更することで遷移を発⽕する
18DeepLinkを実装する© Recruit Co., Ltd. All Rights Reserved.onOpenURLでURLスキームを受け取り、ViewRouterを⽤いて画⾯遷移を発⽕する
ハマりポイント①© Recruit Co., Ltd. All Rights Reserved19
20このコードどこに問題があるでしょうか︖
21このコードどこに問題があるでしょうか︖NavigationLinkが2つあることが問題※ iOS15は問題なし
22iOS14&NavigationLink 2つのみの場合挙動が不安定© Recruit Co., Ltd. All Rights Reservedページ3まで遷移すると勝⼿にページ1に戻るページ1 ページ2 ページ3遷移 遷移※デモ動画
23iOS14系&NavigationLink 2つのみの場合挙動が不安定© Recruit Co., Ltd. All Rights Reserved遷移直後に勝⼿に戻る問題の報告NavigationLinkが2つの場合のみ発⽣https://developer.apple.com/forums/thread/677333https://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 Reserved25
26このコードどこに問題があるでしょうか︖© Recruit Co., Ltd. All Rights Reserved特定のボタンがタップされた際に、そのボタンに応じた値を遷移先に渡したいボタンがタップされたらpageAIdを代⼊するpageAIdがあるときのみ、NavigationLinkを⽣成する
27このコードどこに問題があるでしょうか︖© Recruit Co., Ltd. All Rights ReservedNavigationLinkを⽣成した直後に遷移を発⽕していることが問題
28if 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 Reserveddestinationの中でif letを使⽤する
32様々な要件1. DeepLink2. 1画⾯で複数種類のアラートダイアログ3. 1画⾯から複数の画⾯へのモーダル遷移4. カスタムダイアログ / トースト / チュートリアル© Recruit Co., Ltd. All Rights Reserved
331画⾯で複数種類のアラートダイアログを表出する© Recruit Co., Ltd. All Rights Reserved
ハマりポイント③© Recruit Co., Ltd. All Rights Reserved34
35このコードのどこに問題があるでしょうか︖© Recruit Co., Ltd. All Rights Reserved
36このコードのどこに問題があるでしょうか︖© Recruit Co., Ltd. All Rights Reserved1つのViewに対して複数の.alertを利⽤していることが問題※ iOS14 15共に問題あり
371つのViewに対して1つしか.alertは定義できない© Recruit Co., Ltd. All Rights Reserved2つ⽬の.alertのみ有効
382つ⽬のアラートしか表⽰されない© Recruit Co., Ltd. All Rights Reservedアラート1は表⽰されない アラート2は表⽰される
39回避策© Recruit Co., Ltd. All Rights Reserved1つの.alertの中で複数パターン出し分けるアラートのパターンを定義しておく
40様々な要件1. DeepLink2. 1画⾯で複数種類のアラートダイアログ3. 1画⾯から複数の画⾯へのモーダル遷移4. カスタムダイアログ / トースト / チュートリアル© Recruit Co., Ltd. All Rights Reserved
41ある画⾯から⼆つの画⾯にモーダル遷移したい© Recruit Co., Ltd. All Rights Reserved
ハマりポイント④© Recruit Co., Ltd. All Rights Reserved42
43このコードのどこに問題があるでしょうか︖© Recruit Co., Ltd. All Rights Reserved
44このコードのどこに問題があるでしょうか︖© Recruit Co., Ltd. All Rights Reserved1つのViewに対して2つの.fullScreenCoverを利⽤していることが問題※iOS14.5以上は問題ない
45iOS14.5未満では.fullScreenCoverは1つのViewに対して2つ使えない© Recruit Co., Ltd. All Rights Reservedページ1に遷移しない ページ2には遷移する
46回避策(?)© Recruit Co., Ltd. All Rights Reserved1つのEmptyViewに対して1つの.fullScreenCoverを定義する
47iOS14(iOS14.5含む)で正常に動作する© Recruit Co., Ltd. All Rights Reservedページ1に遷移 ページ2に遷移
48iOS15でどちらも動かない© Recruit Co., Ltd. All Rights Reservedページ1に遷移しない ページ2に遷移しない
49苦⾁の回避策© Recruit Co., Ltd. All Rights ReservediOS14.5未満かどうかで実装を変更条件によってmodifierを適⽤するmodifier
50様々な要件1. DeepLink2. 1画⾯で複数種類のアラートダイアログ3. 1画⾯から複数の画⾯へのモーダル遷移4. カスタムダイアログ / トースト / チュートリアル© Recruit Co., Ltd. All Rights Reserved
51TabViewやNavigationViewを含む全画⾯に対してカスタムUIを被せる© Recruit Co., Ltd. All Rights Reserved
ハマりポイント⑤© Recruit Co., Ltd. All Rights Reserved52
53NavigationViewやTabViewの⼦Viewに対してカスタムダイアログを表⽰すると全画⾯に被さらない© Recruit Co., Ltd. All Rights Reserved⼦Viewでダイアログを管理する
54NavigationViewに対してカスタムダイアログを表⽰すれば実現可能だが、ダイアログ等は各タブや遷移先で管理したい© Recruit Co., Ltd. All Rights ReservedNavigationViewに対してカスタムダイアログを宣⾔するTabViewA内でshowDialog変数をTrueにしてダイアログを表⽰する
55UIWindowを活⽤する© Recruit Co., Ltd. All Rights Reserved全画⾯に表⽰したいカスタムUIは全てUIWindowを⽤いて実装
56UIWindowを活⽤する© Recruit Co., Ltd. All Rights ReservedどのViewからでも全画⾯のダイアログが表⽰可能
57UIWindowを利⽤することで、カスタムダイアログの上にさらにチュートリアルを出すことも© Recruit Co., Ltd. All Rights Reservedチュートリアルとカスタムダイアログを別々のWindowで管理しているため、簡単に実現可能
まとめ© Recruit Co., Ltd. All Rights Reserved58
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 ReservedUIの実装速度が向上l レイアウトの記述がシンプルl コンポーネントの再利⽤が容易l Previewで⾼速にUI変更確認l Storyboardやxibと⽐較してレビューが容易….など、メリットを沢⼭感じることができたSwiftUIはハマりポイントもあったが、総じて採⽤してよかった採⽤してよかった理由