2021年9月28日火曜日

【SwiftUI App】WindowGroup の RootView を切り替える方法

 

iOS14 から採用されている SwiftUI App ライフサイクルでは以下のように WindowGroup の中にある View(ここでは ContentView)がアプリケーションの RootView になっています。

@main
struct SampleApp: App {    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

今回はこの RootView を切り替える方法について一例として紹介したいと思います。

 

WindowGroup の RootView を切り替える方法

@StateObject

今回のポイントは @StateObject 修飾子です。

以前より、@State 修飾子と言うものはありました。@State は、Int・String・Bool といった値型の変数の状態をViewと連携させるものでしたが、@StateObjectオブジェクト型(class型)の変数を扱う場合に使用します。

以下のサンプルでは、この @StateObject として宣言したオブジェクトが持つ enum を元に RootView を分岐する例を示します。

RootView 切り替え実装例

AppState シングルトンクラス

class AppState: ObservableObject {
    
    static let shared = AppState()
    private init() {}
    
    enum RootViews {
        case splash
        case main
    }
    @Published private(set) var rootView: RootViews = .splash
    
    func changeRootView(rootView: RootViews) {
        self.rootView = rootView
    }
}

ObservableObject プロトコルに準拠した AppState と言う名前のシングルトンクラスを作成します(SwiftUI らしさを考えると EnvironmentObject で表現しても良いかもしれません)。

enum でスプラッシュ画面(splash)とメイン画面(main)の列挙子を定義しました。この値で WindowGroup の RootView を切り替えます。

SplashView と MainView

struct SplashView: View {
    var body: some View {
        Text("Splash View")
            .foregroundColor(.blue)
            .onAppear() {
                DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
                    AppState.shared.changeRootView(rootView: .main)
                }
            }
    }
}

struct MainView: View {
    var body: some View {
        Text("Main View")
            .foregroundColor(.red)
    }
}

最初は、前者の SplashView が表示されています。そして表示から 2.0 秒後に AppStatechangeRootView で RootView に MainView 指定しています。

@StateObject と WindowGroup での分岐

@main
struct SampleApp: App {
    
    @StateObject private var appState = AppState.shared
    
    var body: some Scene {
        WindowGroup {
            switch appState.rootView {
            case .splash:
                SplashView()
            case .main:
                MainView()
            }
        }
    }
}

AppState.shared インスタンスを @StateObjectappState に紐づけ、WindowGroup ブロック内の switch で RootView を分岐させています。

@StateObject が付加されていなかったり、誤って @State にしてしまっていたりすると動作しませんので注意してください。

 

元ネタ https://www.yururiwork.net/archives/1188

 

 

2021年9月17日金曜日

ASP.NET Identity メモ

 認証用DBの作成方法

テーブルを生成する

Code Firstで実行時に生成されるのはデモとしてはいいのですけど、実務では開発者の意図するタイミングで生成しておきたいこともあります。その場合は、Migrationしてやればいいようです。

ツール -> NuGetパッケージマネージャー -> パッケージマネジャーコンソールを開き、

Enable-Migrations
Add-Migration migration_filename
Update-Database

 

2021年9月14日火曜日

Kotlin JSON DecodeFromString -> 複数のdata classに格納する記述

 Kotlin JSON DecodeFromString -> 複数のdata classに格納する記述

  val vItems = Json.decodeFromString<List<data class>>(jsonStr)

1件だけなら

  val vItem = Json.decodeFromString<data class>(jsonStr)

 

data classは以下の通り

import kotlinx.serialization.Serializable

@Serializable
data class Notice (
val ID: Int,
val UserName: String
)