본문 바로가기

프로젝트/Twitter Clone App (w∕Firebase)

(27)
26. 기본 UI 구현하기 #9 기본 UI 구현하기 #9 프로필 수정 버튼 표시하기 ProfileView에는 EditProfile 버튼이 존재한다. 지금은 본인의 Profile인지 상대방의 Profile인지 구분 없이 Edit Profile을 표시하지만, 이 둘을 구분해 Follow 버튼으로 치환해 표시할 수 있도록 구현해 본다. class ProfileViewModel: ObservableObject { @Published var tweets = [Tweet]() @Published var likedTweets = [Tweet]() private let service = TweetService() private let userService = UserService() let user: User init(user: User) { sel..
25. DB와 연결하기 #4 DB와 연결하기 #4 좋아요 한 Tweet 표시하기 ProfileView의 Likes 탭에는 해당 계정이 작성했던 Tweet도, 답변을 달았던 Tweet도 아닌 좋아요를 눌렀던 Tweet을 표시해야 한다. 이전에 구현한 좋아요 기능에서 사용하는 user-likes 하위 collection 활용하면 굉장히 간단하게 구현할 수 있다. 좋아요 한 Tweet 표시하기 | TweetService, fetchLikedTweets fetchTweets(foruid:) func fetchTweets(foruid uid: String, completion: @escaping([Tweet]) -> Void) { Firestore.firestore().collection("tweets").whereField("uid", i..
24. 기능 구현 #10 기능 구현 #10 좋아요 취소(unLike) 기능 추가하기 좋아요 취소(unLike) 기능 추가하기 | TweetService, unLikeTweet 이미 좋아요가 된 글을 취소할 수 있는 기능이 있어야 한다. Tweet에 관련된 기능인 TweetService LikeTweet, uploadTweet, fetchTweets(), fetchTweets(foruid:) 모두 TweetService에 정의돼 있으므로 unLikeTweet도 해당 파일에 구현하면 된다. likeTweet func likeTweet(_ tweet: Tweet, completion: @escaping() -> Void) { guard let uid = Auth.auth().currentUser?.uid else { return } ..
23. 기능 구현 #9 기능 구현 #9 좋아요 기능 추가하기 SNS에서 빠질 수 없는 좋아요 기능을 구현해 본다. TweetRow의 하트 버튼을 누르면 붉은색으로 표시되고, 이를 모아서 볼 수도 있어야 한다. 기본적인 UI는 이미 존재하는 상태이므로 기능만 구현하면 된다. 좋아요 기능 추가하기 | Tweet model import FirebaseFirestoreSwift import Firebase struct Tweet: Identifiable, Codable { @DocumentID var id: String? let caption: String let timestamp: Timestamp let uid: String var likes: Int var user: User? var didLike: Bool? = false }..
22. 버그수정 #2 버그수정 #2 fetchTweets의 정렬 문제, SideMenu의 배경색 문제 fetchTweets의 정렬 문제 지금도 Tweet들을 Firebase에서 가져오는 데에는 문제가 없지만, 사소하지만 대단히 중요한 문제가 하나 있다. 바로 Tweet이 글을 작성한 순서대로 표시되지 않는다는 점이다. 해당 문제를 해결하기 위해 두 가지 접근법을 사용한다. fetchTweets의 정렬 문제 | FeedView의 경우, Firebase order Firestore.firestore().collection("tweets").order(by: "timestamp", descending: true).getDocuments { snapshot, _ in guard let documents = snapshot?.docu..
21. DB와 연결하기 #3 DB와 연결하기 #3 ProfileView에 실제 데이터 연결하기 ProfileView에 실제 데이터 연결하기 | ProfileView 더보기 Source import SwiftUI import Kingfisher struct ProfileView: View { @State private var selectedFilter: TweetFilterViewModel = .tweets @Environment(\.dismiss) var dismiss @Namespace var animation private let user: User init(user: User) { self.user = user } var body: some View { VStack(alignment: .leading) { headerView ..
20. 기능 구현 #8 기능 구현 #8 TweetRowView 데이터 연결 TweetRowView 데이터 연결 | FeedViewModel 이전에 구현한 대로라면 FeedView가 표시되고, FeedViewModel을 호출하는 순간, fetchTweets 메서드가 작동하게 된다. class FeedViewModel: ObservableObject { @Published var tweets = [Tweet]() let service = TweetService() init() { fetchTweets() } func fetchTweets() { service.fetchTweets { tweets in self.tweets = tweets } } } Tweet은 위와 같이 내용, 좋아요 카운트, 작성 날짜, 유저 정보(uid)를 가..
19. 기능 구현 #7 기능 구현 #7 Tweet 가져오기 Tweet 가져오기 | Tweet Model Firebase에 저장된 Tweet의 모습이다. 이 데이터들을 앱에서 보여줄 수 있도록 객체화가 필요하다. import FirebaseFirestoreSwift import Firebase struct Tweet: Identifiable, Codable { @DocumentID var id: String? let caption: String let timestamp: Timestamp let uid: String var likes: Int var user: User? } Identifiable과 Codable 프로토콜을 채용한 Tweet 구조체를 하나 정의했다. Tweet의 id에 해당하는 DocumentID는 Identif..
18. 기능 구현 #6 기능 구현 #6 트윗 작성 트윗 작성 | NewTweetView struct NewTweetView: View { @State private var caption = "" @Environment(\.dismiss) var dismiss var body: some View { VStack { HStack { Button { dismiss() } label: { Text("Cancel") .foregroundColor(Color(.systemBlue)) } Spacer() Button { print("tweet") } label: { Text("Tweet") .bold() .foregroundColor(.white) .padding(.horizontal) .padding(.vertical, 8) .backg..
17. 기능 구현 #5 기능 구현 #5 유저 검색 기능 유저 검색 기능 | SearchBar 29. List의 부가 기능 구현하기 List의 부가 기능 구현하기 Pull Refresh Apple Developer Documentation developer.apple.com 화면을 아래로 끌어당겨 새로고침 하는 iOS의 가장 보편적인 새로고침 방식이다. struct PullToRefresh: View { @State private var ite chillog.page SwiftUI에서도 SearchBar를 제공하지만 List나 NavigationView 등 특정 View만 지원하므로 심미적인 목적이나 구현 스타일에 따라 새롭게 구성할 수 있어야 한다. struct SearchBar: View { @Binding var text:..