【SwiftUI】Life Cycle SwiftUI App なんだこれ、、

どうも、こんにちは。
ありきたりな、佐藤です。
そう、僕です。


## Xcode12から、Life Cycle: SwiftUI Appが増えていた。

最近Xcodeを12.1にアップデートしました。
最近SwiftUI触ってないなー何か作ってみよーと思い
アプリを作ろうとしたんです。
見た事のない項目がありました。
**Life Cycle** なんて項目があるじゃない!
えーと、選べるのは

- UIKit AppDelegate
- SwiftUI App

**SwiftUI App** ！うん！知らない！君に決めたっ！

## 環境

- XCode12.1 (12A7403)

## 初期ファイル構成
「AppDelegate.Swift」、「SceneDelegate.swift」がいつも鎮座してるけど
いつもの君たちはいない。。「アプリ名App.swift」がいる。。
とても、シンプルになっていて、とても好きですが。
 <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863439/0e93d0b2-86ac-7613-f497-6a66c56cce4f.png" width=75%>

## ライフルサイクルはどうやって管理するの？
起動時に、〇〇処理して、
バックグラウンド行く時に、□□処理して、などよくAppdelegateにお世話になってたけど
なくなってます。
どうやるのだろうと、調べてみました。

## ScenePhase
知らなかっただけで、[ScenePhase](https://developer.apple.com/documentation/swiftui/scenephase)にしっかり記載されていました。
**@Environment(\.scenePhase)**を追加し、状態を取得するようです。

```swift

@Environment(\.scenePhase) private var scenePhase
```

WindowGroupに.onChangeを追加し下記のようにして実行してみます。

```swift
struct MyAppApp: App {

    @Environment(\.scenePhase) private var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { phase in
            switch phase {
            case .active:
                NSLog("・scenePhase : active")
            case .inactive:
                NSLog("・scenePhase : inactive")
            case .background:
                NSLog("・scenePhase : background")
            @unknown default:
                NSLog("・scenePhase : @unknown")
            }
        }
    }
}
```

起動のみ

```
2020-11-11 15:07:19.852837+0900 MyApp[65073:4732940] ・scenePhase : active
```

起動後に、ホーム画面に戻る

```
2020-11-11 15:07:19.852837+0900 MyApp[65073:4732940] ・scenePhase : active
2020-11-11 15:11:43.979548+0900 MyApp[65073:4732940] ・scenePhase : inactive
2020-11-11 15:11:44.701499+0900 MyApp[65073:4732940] ・scenePhase : background
```

１、起動後に、ホーム画面に戻る
２、ホーム画面でアイコンタップ

```
2020-11-11 15:07:19.852837+0900 MyApp[65073:4732940] ・scenePhase : active
2020-11-11 15:11:43.979548+0900 MyApp[65073:4732940] ・scenePhase : inactive
2020-11-11 15:11:44.701499+0900 MyApp[65073:4732940] ・scenePhase : background
2020-11-11 15:12:52.412940+0900 MyApp[65073:4732940] ・scenePhase : inactive
2020-11-11 15:12:52.720381+0900 MyApp[65073:4732940] ・scenePhase : active
```

まぁ、これでも大丈夫っちゃ大丈夫だけど。。。

## UIApplicationDelegateAdaptorを使用する方法もある
下記を実装し、「didFinishLaunchingWithOptions」を実装する

```
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
```

```swift
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        NSLog("・\(#function)")
        return true
    }
}
```

起動のみ

```
2020-11-11 15:16:35.748372+0900 MyApp[68348:4752272] ・application(_:didFinishLaunchingWithOptions:)
2020-11-11 15:16:35.780670+0900 MyApp[68348:4752272] ・scenePhase : active
```

うむ。いつもの通りだ^^

次に、didFinishLaunchingWithOptionsでNotificationCenterを書いてLogを出してみた。

```swift
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        NSLog("・\(#function)")
        
        NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: .main) { _ in
            NSLog("・didBecomeActiveNotification")
        }
        
        NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: .main) { _ in
            NSLog("・didEnterBackgroundNotification")
        }

        NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification, object: nil, queue: .main) { _ in
            NSLog("・willResignActiveNotification")
        }
        
        NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: .main) { _ in
            NSLog("・willEnterForegroundNotification")
        }

        NotificationCenter.default.addObserver(forName: UIApplication.willTerminateNotification, object: nil, queue: .main) { _ in
            NSLog("・willTerminateNotification")
        }
        return true
    }
```


起動のみ

```
2020-11-11 16:11:55.657872+0900 MyApp[86873:4856069] ・application(_:didFinishLaunchingWithOptions:)
2020-11-11 16:11:55.669768+0900 MyApp[86873:4856069] ・scenePhase : active
2020-11-11 16:11:55.670455+0900 MyApp[86873:4856069] ・willEnterForegroundNotification
2020-11-11 16:11:55.670839+0900 MyApp[86873:4856069] ・didBecomeActiveNotification
```

起動後に、ホーム画面に戻る

```
2020-11-11 16:11:55.657872+0900 MyApp[86873:4856069] ・application(_:didFinishLaunchingWithOptions:)
2020-11-11 16:11:55.669768+0900 MyApp[86873:4856069] ・scenePhase : active
2020-11-11 16:11:55.670455+0900 MyApp[86873:4856069] ・willEnterForegroundNotification
2020-11-11 16:11:55.670839+0900 MyApp[86873:4856069] ・didBecomeActiveNotification

2020-11-11 16:12:40.028331+0900 MyApp[86873:4856069] ・scenePhase : inactive
2020-11-11 16:12:40.028830+0900 MyApp[86873:4856069] ・willResignActiveNotification
2020-11-11 16:12:41.232107+0900 MyApp[86873:4856069] ・scenePhase : background
2020-11-11 16:12:41.256543+0900 MyApp[86873:4856069] ・didEnterBackgroundNotification
```

１、起動後に、ホーム画面に戻る
２、ホーム画面でアイコンタップ

```
// App起動
2020-11-11 16:11:55.657872+0900 MyApp[86873:4856069] ・application(_:didFinishLaunchingWithOptions:)
2020-11-11 16:11:55.669768+0900 MyApp[86873:4856069] ・scenePhase : active
2020-11-11 16:11:55.670455+0900 MyApp[86873:4856069] ・willEnterForegroundNotification
2020-11-11 16:11:55.670839+0900 MyApp[86873:4856069] ・didBecomeActiveNotification
// バックグラウンドへ
2020-11-11 16:12:40.028331+0900 MyApp[86873:4856069] ・scenePhase : inactive
2020-11-11 16:12:40.028830+0900 MyApp[86873:4856069] ・willResignActiveNotification
2020-11-11 16:12:41.232107+0900 MyApp[86873:4856069] ・scenePhase : background
2020-11-11 16:12:41.256543+0900 MyApp[86873:4856069] ・didEnterBackgroundNotification
// フォアグラウンドへ
2020-11-11 16:13:29.154073+0900 MyApp[86873:4856069] ・scenePhase : inactive
2020-11-11 16:13:29.154485+0900 MyApp[86873:4856069] ・willEnterForegroundNotification
2020-11-11 16:13:29.466073+0900 MyApp[86873:4856069] ・scenePhase : active
2020-11-11 16:13:29.467123+0900 MyApp[86873:4856069] ・didBecomeActiveNotification
```

実装次第で、今までの通りにできそうでよかった。

## これから
ScenePhaseだけでも、大方は、対応ができそうではありますが、細かく分けたい場合は、
今までの通りAppDelegateを使用した方が、無難かなって思います。
まだ、急いで、SwiftUIAppに対応することもなく、UIKit AppDelegateで作れば何も気にすることはないわけですけど、気になってしまったので！！

今日はここまで！！