UIkit経験者がSwiftUIを始める際に参考になる情報のまとめ

## 書籍
[1人でアプリを作る人を支えるSwiftUI開発レシピ](https://www.amazon.co.jp/dp/B08NCXF81P/ref=cm_sw_r_tw_dp_MJAPQ985KWCCM1MQF5TK?_encoding=UTF8&psc=1)

WWDCのセッションの内容がコンパクトにわかりやすくまとまっているので、これだけでも十分と言えますが、SwiftUIに関連するXcodeの使い方は載っていないので、そこはWWDCやチュートリアルで補完すると丁度良くなります。

## Apple公式
### チュートリアル
https://developer.apple.com/tutorials/swiftui

### WWDC

#### 2021
- [What's new in SwiftUI](https://developer.apple.com/videos/play/wwdc2021/10018/)
- [Direct and reflect focus in SwiftUI](https://developer.apple.com/videos/play/wwdc2021/10023/)

#### 2020
- [What's new in SwiftUI](https://developer.apple.com/videos/play/wwdc2020/10041/)
- [Introduction to SwiftUI](https://developer.apple.com/videos/play/wwdc2020/10119/)
- [Data Essentials in SwiftUI](https://developer.apple.com/videos/play/wwdc2020/10040)
- [App essentials in SwiftUI](https://developer.apple.com/videos/play/wwdc2020/10037)
- [Stacks, Grids, and Outlines in SwiftUI](https://developer.apple.com/videos/play/wwdc2020/10031)

#### 2019
- [Building Custom Views with SwiftUI](https://developer.apple.com/videos/play/wwdc2019/237)
- [Data Flow Through SwiftUI](https://developer.apple.com/videos/play/wwdc2019/226)
- [Introducing Combine](https://developer.apple.com/videos/play/wwdc2019/722)
- [Combine in Practice](https://developer.apple.com/videos/play/wwdc2019/721)
- [SwiftUI Essentials](https://developer.apple.com/videos/play/wwdc2019/216)
- [Structure your app for SwiftUI previews](https://developer.apple.com/videos/play/wwdc2020/10149)

### サンプルアプリ
サンプルアプリの中にXcode14が必要なものがあるので、事前にインストール推奨
https://developer.apple.com/tutorials/sample-apps

### ドキュメント
SwiftUIで何が出来るか引き出しをたくさん用意すると便利なので、索引でもいいのでさらっと流し読み
https://developer.apple.com/documentation/swiftui/

## 記事関連
SwiftUIはバージョンアップごとに大きな変更が入っているので、記述が変わっているという前提で読むとよいでしょう。

### Qiita
- [個人的に有用だと感じたテクニック集を『Effective SwiftUI 候補（仮説）』として公開しました。](https://qiita.com/YusukeHosonuma/items/9889eee79d7c760f4d63)
- [PublishedがどのようにSwiftUIのViewを更新するのか](https://qiita.com/yimajo/items/8846207d2b7a17ace809)
- [動作原理から理解するSwiftUI](https://qiita.com/yusuga/items/5ad13bf54952e1daca2e)
- [EnvironmentValuesを制するものはSwiftUIを制する](https://qiita.com/1amageek/items/59c6bb32a6627b4fb712)
- [SwiftUIのViewはなぜクロージャでselfを書いても循環参照しないのか](https://qiita.com/yimajo/items/4dde5b297f61b699d844)
- [SwiftUIをジェネリクスでプレビューしやすくする](https://qiita.com/rymshm/items/a5469671194701e36861)
- [SwiftUIのListでスクロール末尾で次のデータを読み込み表示する方法](https://qiita.com/shiz/items/f0f663f8fb926d914990)
- [Sketchと1対1を目指すAtomic designなSwiftUIの作り方](https://qiita.com/YutoMizutani/items/026133035c36bf0652ba)
- [SwiftUIとUIKit、結局どっちを使えば良いのかを考える](https://qiita.com/noppefoxwolf/items/7940f5b8b132b825c545)
- [SwiftUIのSubViewは画面更新ごとに生成と破壊を繰り返す](https://qiita.com/yimajo/items/a0180e66f4f93120287e)
- [SwiftUIにおける拡張。そして再発明の危険性](https://qiita.com/noppefoxwolf/items/5b65ab3d62acd83a79cc)
- [SwiftUIアプリケーション開発の不足を補うSwiftUIX](https://qiita.com/yosshi4486/items/3d92f81feaabc1049b4c)
- [SwiftUIのAlignment Guide まとめ](https://qiita.com/shiz/items/0c41d20a2cb7b0748875)
- [え、onAppearまだ使ってるの？！](https://qiita.com/naoKyo/items/862a2cb1664a8dad4128)
- [SwiftUI の Preference の基礎](https://qiita.com/maiyama18/items/a64bab2094750319ef8d)
- [SwiftUIの不思議な機能を実現する変数展開"\()"について調べた](https://qiita.com/ensan_hcl/items/d9b0fdadec8ca77a556c)
- [SwiftUIのsheet（ModalView）を出し分ける](https://qiita.com/1amageek/items/e90e1cfb0ad497e8b27a)
- [SwiftUI 時代の依存関係逆転のプラクティス [beta]](https://qiita.com/lovee/items/0edb7e692416172222a5)
- [Combine+Alamofire+SwiftUIでAPI実行](https://qiita.com/shira-shun/items/778e65308f26860664fc)
- [Combineを使ってMVVMでNotificationCenterを実装する](https://qiita.com/hcrane/items/48fbf9ccde2090e7202c)
- [もっともシンプルな SwiftUI - MVVM](https://qiita.com/john-rocky/items/88b45e18bd48e3dbc87c)
- [SwiftUI+Combineの備忘録とMVVM with Combineチュートリアル for iOSを模倣してQiita記事取得サンプル作ってみた](https://qiita.com/kazy_dev/items/8794c0fef0ae808205f5)
- [SwiftUI + Combine で MVVM & Clean Architecture な設計を考えてみた](https://qiita.com/inokinn/items/7c421f3742e7c0380cdc)

## アーキテクチャ
### MVVM
- [ラクマでのSwiftUI導入方針とTips ](https://speakerdeck.com/darquro/rakuma-swiftui-introduction-policy-and-tips?slide=3)
- [SwiftUIで使うViewModelのInputsとOutputsを表現したい](https://zenn.dev/fuziki/articles/15d3c252322e69cc4704)

### VIPER
- [SwiftUI を活用した「レシピ」×「買い物」の新機能開発](https://techlife.cookpad.com/entry/2021/01/18/kaimono-swift-ui)
- [SwiftUIでVIPERのiOSアプリをつくってみた](https://zenn.dev/st43/articles/91fd6558e311b3)
- [SwiftUIアプリをVIPERアーキテクチャーで作り画面遷移処理をまとめる
](https://blog.personal-factory.com/2020/05/31/viper-architecture-in-swiftui/)
- [VIPERアーキテクチャでSwiftUIを利用するサンプルコードを動かして理解したい](https://zenn.dev/yimajo/articles/d50f5bb85c96c5)

## view.bodyの組み方について
そこそこの画面をbodyに直接書いてしまうと、読みにくいのでコンポーネントごとにviewを組み立てるようにするのを推奨。
UIkitの頃はカスタムViewを用意して、awakeFromNib()などに装飾コードを書いたりすることが多くなりがちですが、bodyにそれを書いてしまうとわかりにくくなるのでコンポーネントにする。
アトミックデザインを頭の片隅におきつつ、ある程度整理整頓できていれば良いかなと個人的に思います。
[モバイルアプリ開発において宣言的UIフレームワークを利用する際のコンポーネント粒度についての考察](https://techlife.cookpad.com/entry/2021/12/17/103000)

## プレビューをどこまで整備するか
こんな感じにプレビュー用のViewModelを用意し、中身をAPIが返すデータに差し替えたりすると現実に即したプレビューができる反面、APIが変更になった時にデータ修正が必要になってくるので注意。スタブ用のVMを用意せずとも実VMを使っても良い（ただし、欲しいデータが必ずしも取得できるとは限らない）

モックデータは`Preview Assets.xcassets`に入れとくとプレビューの時だけ使えるようにできるのでおすすめ。

```Swift
protocol ViewModelProtocol {
  var items: [Item] { get }
}

struct SampleViewModel: ViewModelProtocol {
  @Published items...実APIから取得
}

struct SampleViewModelStub: ViewModelProtocol {
  @Published items...Preview用のjsonを変換したのを返す
}

struct ContentView: <ViewModel: ViewModelProtocol>: View {
    @ObservedObject private var viewModel: ViewModel
    
    var body: some View {
        Text("Hello")
    }
}

struct SampleView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(SampleViewModelStub())
    }
}
```

## UI Debug
view.bodyに直接printは書けないので、以下を参照
https://zenn.dev/bannzai/articles/20557106b4ba7b
https://ameblo.jp/kamekame0912/entry-12567283588.html

## TIPS
- [ViewDidLoadModifier](https://stackoverflow.com/questions/56496359/swiftui-view-viewdidload)
- [onApperで不審な動き？](https://qiita.com/naoKyo/items/862a2cb1664a8dad4128)
- [UIkitのviewWillApperなどをSwiftUIで使う](https://www.yururiwork.net/archives/1058)

## SwiftUIにおけるテスト
https://qiita.com/turara/items/dd7bee391962f945256f

## 推奨iOSバージョン
iOS13/14をサポートする場合、UIkitで当たり前に使える機能が標準実装されていなく、15から色々使えるようになってきているので特段の理由がなければ15からが推奨
- 非同期画像ロードに困る(AsyncImageが使えない)
- present/dismissの使用に癖がある
- UIにフォーカスを当てられない(よくあるTextFiledに最初からフォーカス合わせるとか）
- Navigation周りにバグが多い。
- Pull to Refreshがない

## UIkitとSwiftUIのチートシート
https://qiita.com/hcrane/items/eb847ca7fb7a0b9e8073
https://fuckingswiftui.com/

## RxSwiftとCombineのチートシート
RxSwift経験している人向けにCombineだとどれだっけの対応表
https://github.com/CombineCommunity/rxswift-to-combine-cheatsheet