인스타그램을 보면 피드 화면에는 모든 피드가 랜덤으로 나타나고 유저의 프로필을 들어가면 해당 유저가 작성한 피드만 나타난다 앱을 만들다 보면 이러한 경우가 종종 발생한다 그럴때 어떻게 로직을 구성해야 할지 잘 모르겠고 이 방식이 맞나 고민이 됬었다.
탐색화면으로 가면 모든 게시물을 보여준다 이러한 경우에는 모든 게시물을 가져오도록 기능을 구현하면 된다.
하지만 특정 유저의 게시물을 갔을때는 유저가 작성한 게시물만 나타도록 해야한다 가장 간단한 방법은 현재 SearchViewModel 에서 fetchPosts 메서드의 인자로 유저의 id를 받고 해당 유저의 id가 존재하면 특정 유저의 id를 가져오고 id가 존재하지 않는다면 모든 게시물을 가져오는 방식을 생각했다.
해당 방식을 사용할 수 있지만 PostGridVIew는 여러개의 화면에서 재사용이 되기 때문에 gridView의 데이터를 관리하는 별도의 뷰모델 파일을 만들어 줬다 해당 뷰모델에 설정값만 넘겨주면 모든 피드를 보여주거나 필터링된 피드 결과를 보여준다.
enum PostGridConfiguration {
case explore
case profile(String)
}
설정값을 enum으로 선언해준다.
class PostGridViewModel: ObservableObject {
@Published var posts = [Post]()
let config: PostGridConfiguration
init(config: PostGridConfiguration) {
self.config = config
fetchPost(forConfig: config)
}
}
초기화시 설정값과 설정값에 따른 데이터를 가져오도록 config 값을 fetchPost 에 파라미터로 넘겨준다.
func fetchPost(forConfig config: PostGridConfiguration) {
switch config {
case .explore:
fetchExplorePagePosts()
case .profile(let uid):
fetchUserPosts(forUid: uid)
}
}
func fetchExplorePagePosts() {
COLLECTION_POSTS.getDocuments { snapShot, error in
guard let document = snapShot?.documents else { return }
self.posts = document.compactMap {(try? $0.data(as: Post.self))}
}
}
func fetchUserPosts(forUid uid: String) {
COLLECTION_POSTS.whereField("ownerUid", isEqualTo: uid).getDocuments { snapShot, _ in
guard let document = snapShot?.documents else { return }
self.posts = document.compactMap {(try? $0.data(as: Post.self))}
}
}
fetchPost 에서는 설정값에 따라서 다른 데이터를 가져오고 가져온 데이터를 posts 라는 변수에 저장한다.
struct ProfileView: View {
let user: User
@ObservedObject var viewModel: ProfileViewModel
// @ObservedObject var viewModel: ProfileViewModel = ProfileViewModel(user: user) 대신 아래처럼 init을 이용한다
// 리스트에서 받아온 유저정보로 ProfileViewModel 인스턴스를 생성
init(user: User) {
self.user = user
self.viewModel = ProfileViewModel(user: user)
}
var body: some View {
ScrollView {
VStack(spacing: 32){
ProfileHeaderView(viewModel: viewModel)
PostGridView(config: .profile(user.id ?? ""))
}.padding(.top)
}
}
}
ProfileView 에서는 해당 뷰가 가지고있는 user id를 PostGridView에 넘겨준다 그리고 PostGridView는 해당 id를 받아서 새로운 뷰모델 인스턴스를 생성하고 해당 유저의 피드를 보여준다.
만약 상황에 따라서 다른 결과를 보여줘야 하면서 여러개의 화면에서 재사용 된다면 설정값을 받아서 해당 뷰에서 새로운 뷰모델 인스턴스를 생성해서 보여주는 방식을 사용해보자!
'iOS' 카테고리의 다른 글
SwiftUI 앱에서 Coordinator Pattern 적용하기 (0) | 2024.08.08 |
---|---|
[SwiftUI] UIViewRepresentable을 이용하여 SwiftUI에서 UIKit 뷰 사용하기 (0) | 2023.12.16 |
[iOS] Swift File I/O (1) | 2023.11.21 |
[iOS/SwiftUI] @StateObject, @ObservedObject의 차이점 (1) | 2023.11.20 |