🌐
[SwiftUI]インスタンスじゃなくてidやnameの値を保持しておきたい!
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()
}
}
}
今回はここまで!
[参考・引用]
Discussion
👍
👏