DB와 연결하기 #1
Link UserData to SideMenu
Link UserData to SideMenu
| AuthViewModel
class AuthViewModel: ObservableObject {
@Published var userSession: FirebaseAuth.User?
@Published var didAuthenticateUser = false
@Published var currentUser: User?
private var tempUserSession: FirebaseAuth.User?
private let service = UserService()
init() {
self.userSession = Auth.auth().currentUser
fetchUser()
}
현재 접속 중인 유저를 확인하기 위해 currentUser 인스턴스를 생성한다.
형식은 '11. 기능 구현하기 #3'에서 정의한 User다.
Link UserData to SideMenu
| UserService
before
struct UserService {
func fetchUser(withUid uid: String) {
Firestore.firestore().collection("users").document(uid).getDocument { snapshot, _ in
guard let snapshot = snapshot else {
return
}
guard let user = try? snapshot.data(as: User.self) else {
return
}
}
}
}
after
struct UserService {
func fetchUser(withUid uid: String, completion: @escaping(User) -> Void) {
Firestore.firestore().collection("users").document(uid).getDocument { snapshot, _ in
guard let snapshot = snapshot else {
return
}
guard let user = try? snapshot.data(as: User.self) else {
return
}
completion(user)
}
}
}
fetchUser를 통해 가져온 데이터는 completionHandler로 전달할 수 있도록 코드를 수정한다.
parameter에 completion이 추가됐고, '@escaping'을 지정한다.
이 과정을 통해 정의한 메서드는 completion을 호출하는 것 만으로 completionHandler에 결과를 전달할 수 있다.
Link UserData to SideMenu
| AuthViewModel
class AuthViewModel: ObservableObject {
@Published var userSession: FirebaseAuth.User?
@Published var didAuthenticateUser = false
@Published var currentUser: User?
private var tempUserSession: FirebaseAuth.User?
private let service = UserService()
init() {
self.userSession = Auth.auth().currentUser
fetchUser()
}
.
.
.
func fetchUser() {
guard let uid = self.userSession?.uid else {
return
}
service.fetchUser(withUid: uid) { user in
self.currentUser = user
}
}
}
AuthViewModel의 currentUser에 fetchUser의 결과를 저장한다.
Link UserData to SideMenu
| SideMenu
struct SideMenuView: View {
@EnvironmentObject var authViewModel: AuthViewModel
var body: some View {
if let user = authViewModel.currentUser {
VStack(alignment: .leading, spacing: 32) {
VStack(alignment: .leading) {
Circle()
.frame(width: 48, height: 48)
VStack(alignment: .leading, spacing: 4) {
Text(user.fullname)
.font(.headline)
Text("@\(user.username)")
.font(.caption)
.foregroundColor(.gray)
}
UserStatsView()
.padding(.vertical)
}
.padding(.leading)
ForEach(SideMenuViewModel.allCases, id: \.rawValue) { viewModel in
if viewModel == .profile {
NavigationLink(destination: ProfileView()) {
SideMenuRowView(viewModel: viewModel)
}
} else if viewModel == .logout {
Button {
authViewModel.signOut()
} label: {
SideMenuRowView(viewModel: viewModel)
}
} else {
SideMenuRowView(viewModel: viewModel)
}
}
Spacer()
}
.background(Color.white)
}
}
}
SideMenu의 모든 View를 'if-let'을 사용해 분기한다.
currentUser를 binding 불가능한 경우 SideMenu를 표시할 수 없다.
지금 당장 표시할 수 있는 데이터를 표시해 보자.
fullname과 username을 형식에 맞게 전달하면 된다.
'프로젝트 > Twitter Clone App (w∕Firebase)' 카테고리의 다른 글
14. 버그 수정 #1 (0) | 2023.01.11 |
---|---|
13. DB와 연결하기 #2 (0) | 2023.01.10 |
11. 기능 구현하기 #3 (0) | 2022.12.22 |
10. 기능 구현하기 #2 (0) | 2022.12.20 |
09. 기능 구현하기 #1 (0) | 2022.12.13 |