기능구현 #4
ExploreView
ExploreView
| UserService > fetchUser
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)
}
}
}
UserService는 현재 fetchUser 메서드를 가지고 있다.
uid를 전달받아 일치하는 데이터를 반환하는 기능을 한다.
비슷한 방식으로 유저를 검색하도록 구현한다.
func fetchUsers(completion: @escaping([User]) -> Void) {
}
fetchUsers라는 이름의 메서드를 정의한다.
해당 메서드는 결과값을 completion에 전달해 추가적인 기능을 하도록 구현할 예정이다.
func fetchUsers(completion: @escaping([User]) -> Void) {
var users = [User]()
}
전달할 데이터는 users 배열에 저장한다.
func fetchUsers(completion: @escaping([User]) -> Void) {
var users = [User]()
Firestore.firestore().collection("users").getDocuments { snapshot, _ in
guard let documents = snapshot?.documents else {
return
}
documents.forEach { document in
guard let user = try? document.data(as: User.self) else {
return
}
users.append(user)
}
completion(users)
}
}
이후엔 fetchUser 메서드와 동일한 방식으로 데이터를 가져온 뒤 users에 저장해 completion에 전달하면 된다.
ExploreView
| ExploreViewModel
class ExploreViewModel: ObservableObject {
@Published var users = [User]()
let service = UserService()
init() {
fetchUsers()
}
func fetchUsers() {
service.fetchUsers { users in
self.users = users
print("Users are \(users)")
}
}
}
ExploreView에서 사용할 ExploreViewModel을 구성한다.
생성자에서 호출할 수 있도록 메서드를 재정의 하고, Published로 선언된 users 배열에 결과를 저장한다.
이제 해당 ViewModel이 초기화 될 때 users에 사용자의 목록이 저장되고,
ViewModel의 users 속성으로 접근할 수 있다.
ExploreView
| UserRowView
struct UserRowView: View {
var body: some View {
HStack(spacing: 12) {
Circle()
.frame(width: 45, height: 45)
VStack(alignment: .leading, spacing: 4) {
Text("user1")
.font(.subheadline).bold()
.foregroundColor(.black)
Text("almost admin")
.font(.subheadline)
.foregroundColor(.gray)
}
Spacer()
}
.padding(.horizontal)
.padding(.vertical, 4)
}
}
기존의 UserRowView는 사용자의 실제 데이터 대신 더미 데이터를 표시하고 있다.
지금부터는 실제 데이터를 받아와 표시할 수 있도록 코드를 수정한다.
import SwiftUI
import Kingfisher
struct UserRowView: View {
var body: some View {
HStack(spacing: 12) {
.
.
.
UserRowView는 각 계정의 프로필 사진을 표시할 수 있어야 한다.
앞서 추가한 Kingfisher 패키지를 사용할 수 있도록 Kingfisher를 import 한다.
import SwiftUI
import Kingfisher
struct UserRowView: View {
let user: User
var body: some View {
HStack(spacing: 12) {
.
.
.
UserRowView에 표시할 사용자에 대한 정보를 전달받을 수 있게 User 형식의 user 파라미터를 선언한다.
struct UserRowView: View {
let user: User
var body: some View {
HStack(spacing: 12) {
KFImage(URL(string: user.profileImageUrl))
.resizable()
.scaledToFill()
.clipShape(Circle())
.frame(width: 45, height: 45)
.
.
.
전달받은 user 파라미터의 profileImageUrl을 KFImage 메서드에 전달해 프로필사진을 받아 오고, 이를 표시한다.
struct UserRowView: View {
let user: User
var body: some View {
HStack(spacing: 12) {
KFImage(URL(string: user.profileImageUrl))
.resizable()
.scaledToFill()
.clipShape(Circle())
.frame(width: 45, height: 45)
VStack(alignment: .leading, spacing: 4) {
Text(user.username)
.font(.subheadline).bold()
.foregroundColor(.black)
Text(user.fullname)
.font(.subheadline)
.foregroundColor(.gray)
}
.
.
.
계정명과 사용자 이름도 user의 username과 fullname 속성에 접근해 대체한다.
ExploreView
| ExploreView
struct ExploreView: View {
@ObservedObject var viewModel = ExploreViewModel()
}
ExploreView는 앞서 구현한 ExploreViewModel을 ObservableObject 형식의 viewModel 인스턴스로 선언한다.
이 과정에서 유저들의 목록을 가져와 viewModel 인스턴스 안의 users에 저장한다.
struct ExploreView: View {
@ObservedObject var viewModel = ExploreViewModel()
var body: some View {
VStack {
ScrollView {
LazyVStack {
ForEach(viewModel.users) { user in
NavigationLink {
ProfileView(user: user)
} label: {
UserRowView(user: user)
}
}
}
}
}
.navigationTitle("Explore")
.navigationBarTitleDisplayMode(.inline)
}
}
이제는 ExploreView에서 ProfileView와 UserRowView에 전달할 user가 존재하므로,
각각에 파라미터로 전달해 구성한다.
'프로젝트 > Twitter Clone App (w∕Firebase)' 카테고리의 다른 글
17. 기능 구현 #5 (0) | 2023.01.12 |
---|---|
16. 코드 가독성 개선 (0) | 2023.01.11 |
14. 버그 수정 #1 (0) | 2023.01.11 |
13. DB와 연결하기 #2 (0) | 2023.01.10 |
12. DB와 연결하기 #1 (0) | 2023.01.05 |