🟨 구현 화면
🟨 ProfileDataFormViewViewModel.swift
import Foundation
import Combine
import UIKit
import FirebaseAuth
import FirebaseStorage
final class ProfileDataFormViewViewModel: ObservableObject {
private var subscriptions: Set<AnyCancellable> = []
@Published var displayName: String?
@Published var username: String?
@Published var bio: String?
@Published var avatarPath: String?
@Published var imageData: UIImage?
@Published var isFormValid: Bool = false
@Published var error: String = ""
@Published var isOnboardingFinished: Bool = false
// user 정보를 적는데 필요한 간단한 규칙 정도
func validateUserProfileForm() {
guard let displayName = displayName,
displayName.count > 2,
let username = username,
username.count > 2,
let bio = bio,
bio.count > 2,
imageData != nil else {
isFormValid = false
return
}
isFormValid = true
}
func uploadAvatar() {
let randomID = UUID().uuidString
guard let imageData = imageData?.jpegData(compressionQuality: 0.5) else { return }
let metaData = StorageMetadata()
metaData.contentType = "image/jpeg"
StorageManager.shared.uploadProfilePhoto(with: randomID, image: imageData, metaData: metaData)
.flatMap({ metaData in
StorageManager.shared.getDownloadURL(for: metaData.path)
})
.sink { [weak self] completion in
switch completion {
case .failure(let error):
print(error.localizedDescription)
self?.error = error.localizedDescription
case .finished:
self?.updateUserData()
}
} receiveValue: { [weak self] url in
self?.avatarPath = url.absoluteString
}
.store(in: &subscriptions)
}
private func updateUserData() {
guard let displayName,
let username,
let bio,
let avatarPath,
let id = Auth.auth().currentUser?.uid else { return }
let updatedFields: [String: Any] = [
"displayName": displayName,
"username": username,
"bio": bio,
"avatarPath": avatarPath,
"isUserOnboarded": true
]
DatabaseManager.shared.collectionUsers(updateFields: updatedFields, for: id)
.sink { [weak self] completion in
if case .failure(let error) = completion {
print(error.localizedDescription)
self?.error = error.localizedDescription
}
} receiveValue: { [weak self] onboardingState in
self?.isOnboardingFinished = onboardingState
}
.store(in: &subscriptions)
}
}
🟨 ProfileViewViewModel.swift
import Foundation
import Combine
import FirebaseAuth
final class ProfileViewViewModel: ObservableObject {
@Published var user: TwitterUser?
@Published var error: String?
// @Published var tweets: [Tweet] = []
private var subscriptions: Set<AnyCancellable> = []
func retreiveUser() {
guard let id = Auth.auth().currentUser?.uid else { return }
DatabaseManager.shared.collectionUsers(retreive: id)
.handleEvents(receiveOutput: { [weak self] user in
self?.user = user
// self?.fetchTweets()
})
.sink { [weak self] completion in
if case .failure(let error) = completion {
self?.error = error.localizedDescription
}
} receiveValue: { [weak self] user in
self?.user = user
}
.store(in: &subscriptions)
}
}
🟨 ProfileViewController.swift
import UIKit
import Combine
import SDWebImage
class ProfileViewController: UIViewController {
private var isStausBarHidden: Bool = true
private var viewModel = ProfileViewViewModel()
private var subscriptions: Set<AnyCancellable> = []
// 상태표시줄 설정
private let statusBar: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .systemBackground
view.layer.opacity = 0
return view
}()
private lazy var headerView = ProfileTableViewHeader(frame: CGRect(x: 0, y: 0, width: profileTableView.frame.width, height: 380))
private let profileTableView: UITableView = {
let tableView = UITableView()
tableView.register(TweetTableViewCell.self, forCellReuseIdentifier: TweetTableViewCell.identifier)
tableView.translatesAutoresizingMaskIntoConstraints = false
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
navigationItem.title = "Profile"
view.addSubview(profileTableView)
view.addSubview(statusBar)
profileTableView.delegate = self
profileTableView.dataSource = self
profileTableView.contentInsetAdjustmentBehavior = .never
// 네비게이션 부분 숨기기 -> HomeView에는 네비게이션 부분이 있다가 -> 프로필에 가면 없어졌다가 -> 다시 돌아오면 HomeView에도 없어져있다.
navigationController?.navigationBar.isHidden = true
configureConstraints()
profileTableView.tableHeaderView = headerView
bindViews()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
viewModel.retreiveUser()
}
private func bindViews() {
viewModel.$user.sink { [weak self] user in
guard let user = user else { return }
self?.headerView.displayNameLabel.text = user.displayName
self?.headerView.userNameLabel.text = "@\(user.username)"
self?.headerView.followersCountLabel.text = "\(user.followersCount)"
self?.headerView.followingCountLabel.text = "\(user.followingCount)"
self?.headerView.userBioLabel.text = user.bio
self?.headerView.profileAvatarImageView.sd_setImage(with: URL(string: user.avatarPath))
}
.store(in: &subscriptions)
}
...
'Clone App > Twitter' 카테고리의 다른 글
[Twitter Clone] Show Tweet in Home View (0) | 2024.06.12 |
---|---|
[Twitter Clone] Connect to profileView (0) | 2024.06.12 |
[Twitter Clone] Connect to Firebase Storage (0) | 2024.06.12 |
[Twitter Clone] Add ProfileDataFormView (0) | 2024.06.11 |
[Twitter Clone] Set user Info into firebase storage (1) | 2024.06.09 |