🌐

[SwiftUI]インスタンスじゃなくてidやnameの値を保持しておきたい!

2024/02/13に公開2

viewごとのインスタンスではないけれども、アプリを起動している最中は値を保管しておきたい!

そんなことはありませんか??

(実際にView中のインスタンスで保持している値を反映できない!という時にいろいろ調べてわかったことの備忘録的なものになります。)

そんな時に役に立つのがシングルトンスタイル
例えば、

viewModel = AuthViewModel()

みたいな感じでインスタンスを作成してその中に作成したuserNameを使い回す。
その時に他のViewで

text(viewModel.userName)

これが表示されない時に使えそう。

ConstUser
import Foundation

final class ConstUser: ObservableObject {
    // インスタンスを参照するためのプロパティ
    static let shared = ConstUser()
    // ユーザID
    var id: String = ""
    // ユーザ名
    var name: String = ""
    // ログイン状態を保持しているか否か
    var isLogIned: Bool = false
    // イニシャライズ
    private init() {
        id = ""
        name = ""
        isLogIned = false
    }

    func logOut() {
        id = ""
        name = ""
        isLogIned = false
    }

//     ユーザ情報セットメソッド
    public static func setConstUser(id: String, name: String) {
        ConstUser.shared.id = id
        ConstUser.shared.name = name
        ConstUser.shared.isLogIned = true
    }
}

これを作成したのちに

func logIn(email: String, password: String) async {
        do {
            let userCredential = try await Auth.auth().signIn(withEmail: email, password: password)
            Task.detached { @MainActor in
                ConstUser.shared.id = userCredential.user.uid
                await self.fetchUserName()
                self.isAuthenticated = true
            }
        } catch {
            //エラーハンドリング
        }
    }

みたいな形でloginメソッドにidのfetchを組み込めば、実際のViewでも使うことができるようになるみたい。

import SwiftUI

struct UserDetailScreen: View {
    var viewModel = AuthService()
    @State private var isPresented = false

    var body: some View {
        VStack(spacing: 20) {
            Text(Const.ProjectName)
                .font(.title)
                .fontWeight(.bold)
                .foregroundColor(.red)
                .padding()
                .frame(height: 200)
            Text("User Name: \(ConstUser.shared.name)")
                .font(.subheadline)
                .foregroundColor(.gray)
                .padding().frame(height: 80)
            Text("User ID: \(ConstUser.shared.id)")
                .font(.subheadline)
                .foregroundColor(.gray)
                .padding()
                .frame(height: 80)
            Button("Log Out") {
                viewModel.signOut()
                ConstUser.shared.logOut()
                isPresented = true
            }.fullScreenCover(isPresented: $isPresented) {
                LogInScreen()
            }
            Spacer()
        }
    }
}

今回はここまで!

[参考・引用]

https://qiita.com/yoshi-eng/items/0767c2e1325c1786e585

Jboy王国メディア

Discussion