Intro
こんにちは!STORES株式会社STORESレジの開発メンバーAdamです!最近 後夜祭 iOSDC 2023で発表した「NavigationView -> NavigationStackにしてみた話」のブログです!見逃した人ぜひ読んでみてね〜
背景
レジアプリがiOS16のみでNavigationViewを使っている・特定の動作でクラッシュ(OUTLINED_FUNCTION_X)するケースがありました。 調べていたところでNavigationStackに置き換えたら起きなくなる
今までのSwiftUI Navigation
今までのSwiftUI Navigationが大まかに3つの方法はあると思います。
- SwiftUIのビューをUIHostingControllerに入れてUIKitのNavigationを使う
- 古い各ビューで実装する(Deprecatedとなった)SwiftUI Navigationを使う
- Router的なものを作ってそこでNavigationを統一する
レジアプリがSwiftUI 1.0から作られているアプリと「良くても悪くてもSwiftUIで頑張る!」って感じだったのでSwiftUIのNavigationを使っている。 最初からSwiftUIで作っているアプリわざわざUIKit入れるのがちょっと違和感を感じました。使ったことある人次のコードみたことあるかな〜
Examples
Root | Destination | |
---|---|---|
Modal | ||
Push |
上記は各ビューに実装する形になるけどもし複雑な遷移した場合, どうやってRootView以外のところでDismissする?ModalだけとじるなどのUIKitで簡単にできるところどうやって実現する?
...
...
...
はい、SwiftUIで頑張るって言ったばかりだけどUIKit使ってしまっている。やっぱりまだ物足りないところあります。。。 普通にUIKitそのまま使ってしまっていた理由:
- DismissFrontViewControllerの場合
- 一画面のModalをDismissする時だけは使う必要ない
- SwiftUIだとModalで別の画面に遷移した場合は簡単にModal閉じれない
- PopToRootも似ているような問題で複数のViewを一気にdismissしたい場合は大変になる(StackのDepthによって何回dismissするべきか)
Navigation Stackについて
iOS 16から二つの新しいNavigationが追加されていました。NavigationStack・NavigationSplitView
今回はNavigationStackのみに集中します
NavigationStack周りで二つの新しいところを紹介したいです。 まずはpresentedItems、こちらは現状のStackのステートをコントロール・トラックできるようになっている 自動的にこの配列がビューが追加・削除でアップデートされるし、自分でもProgramattically追加・削除できる これは嬉しい変更ですね
二つ目はこちらのNavigationLinkの新しいInitializer. init(title:value:) DeprecatedのAPI使っている場合だとpresentedItemsがアプデートされないので注意 Setで考えてもらえれば
NavigationView -> NavigationStackにしてみた
単純にNavigationView -> NavigationStackに置き換えてみました!
今まで通りNavigationView置く場所に代わりにおいたら完了!
意外とそのままいけた!。。。と思っていたら上に紹介したWorkaroundのところがぶっ壊れてた。。。 PopToRootが今まで通りに動いてくれたけどDismissFrontViewControllerが動かない dismissされるはずの画面がそのままになってしまう
レジチーム残っている課題・これからの方針
紹介したばっかりの対応が先のDismiss動くなくなった問題・iOS 16.4+でクラッシュ修正された理由で急ぐ必要無くなりました。 *最近Crashlyticsチェックしたらまだ起きているけど頻度はとても少ない 😇
その古い(Deprecatedとなった)SwiftUI Navigationを使うとワークアラウンドが技術負債になっているため解消したい! 次のナビゲーション考えた時にRouterで作ってみたいと思っている iOS 16まで切れたら新しいStackベースに参考して作り直す計画中
まだ設計中・どうなるかわからないけどイメージは 参考: https://blorenzop.medium.com/routing-navigation-in-swiftui-f1f8ff818937
後夜祭の宣伝
10月31日(火) 19:00~、DroidKaigi 2023に協賛しているWED株式会社さん、GO株式会社さん、株式会社ヤプリさん、とアフターイベントを開催します!ぜひご参加ください〜!
また、 STORES ではモバイルエンジニアを募集しています! 少しでも STORES に興味を持たれた方は、ぜひカジュアル面談やBeer Bashに来ていただけると嬉しいです。 (Beer Bashは STORES のオフィスで美味しいお酒を飲み、美味しいごはんを食べながら雑談するだけの会です)