Site icon image技術メモ

「(swift-zoomin) SwiftUIを使ってiOSアプリを作るシンプルな方法」視聴ログ

ざっくり

  • ViewModelのような、Viewに1対1で対応したObservableObjectは不要なのではないか
  • ViewModelの利用を削除し、以下のような変更を加えたら良いのではないか
    • View側は
      • StoreをenvironmentObjectとして監視
        • ※画面に縛られずにDomainに関する状態を保持するオブジェクト=Store
      • ViewModel内部に並んでいた変数ごとに、@Stateとして保持する
      • ViewModel内部に記載していたロジックは、View側に寄せる

メリット

  • Combineのことを忘れられる
    • ViewModelを用いた書き方だと、SwiftUIのViewのinitializer内部でCombine風の記載が生まれる
      Image in a image block
  • ViewModelを用いた書き方だと、SwiftUIのViewのイニシャライザに渡す値(あるいは、そのイニシャライザ内部で生成されているViewModelに渡す値)をEnvironmentObjectから取得したいケースがあるが、イニシャライザ内部でアクセスできない点で不便であった
    Image in a image block
  • なぜ今までViewModelが求められていたのか
    • UIKitとの共存問題

その他考慮する点

  • テストできる?
    • environmentに突っ込むオブジェクトに関しては差し替え可能だが、Viewのメソッドのテストはできない
      • 返却値が some Viewになってしまう
      Image in a image block
    • その他、以下のような意見
      • そもそもPreviewで静的な表示の確認はできる
      • ロジックだけ別のModelに切り出してModelをテストすればよくない
      • それでも担保できないならUITestでよくないか
  • ViewのコードがFatにならないか?
    • extensionでロジックとレイアウトを分けるだけでも見通しの良さを保ちつつ開発速度を上げることができそう
    • ロジックを適切にモデルに切り出して抑えることもできる
      • 結局ViewModel的なのになってしまう可能性はある
  • ObservationFrameworkを使えるなら、そもそも以下の問題は発生しない?
    • そもそもViewModelがObservableObjectであり、かつ、ObservableObjectを子に持つ場合に、「繋ぎこみ」処理を書く必要がある
      • 繋ぎこみとは、ViewModelのイニシャライザ内部でCombineを用いた更新の伝播に関わる記述のこと
      • この問題は、ObservableObjectがネストされている場合、ComputedPropertyによる演算では、子の変更が親に伝わらない仕組みであるため起こる
    • → ObservationFrameworkでは上記問題が解消される

備忘録

  • StoreのイニシャライザでRepositoryをany HogeProtocol型を指定してインジェクトする
    • ジェネリクスを用いるコトもできなくはないが、型パラメーターのバケツリレーをせずにEnvironment経由で取得したいので
  • 2023のiOSDC SVVSアーキテクチャ
    • Store-View-ViewStateの略
  • MVStateパターンも似た課題感
    • SwiftUIで設計のシンプルさを重視してアプリ作るなら、ViewModel的なのをやめたほうが良いという趣旨は同じ

参照