Trouble shooting
AutoLayout
storyboard IDλ₯Ό μ€μ ν΄λ idλ₯Ό μ°Ύμ μ μλ€λ μλ¬κ° λ°μν¨.
Storyboard doesn't contain a view controller with identifier "ChattingViewController"
μν© μ€λͺ
Main View Controllerμμ Sign In λ²νΌμ ν΄λ¦νλ©΄, ChattingViewControllerκ° λμμΌν¨.
ChattingViewController μ€μ
λ΄κ° μμ±ν μ½λ
@IBAction func didTappedSignInButton(_ sender: UIButton) {
guard let email = emailTextField.text,
let password = passwordTextField.text else { return }
Auth.auth().signIn(withEmail: email, password: password) { [weak self] result, error in
guard let strongSelf = self else { return }
if let error { return }
guard let viewController = self?.storyboard?.instantiateViewController(withIdentifier: "ChattingViewController") as? ChattingViewController else { return }
self?.present(viewController, animated: true, completion: nil)
}
}
μμΈκ³Ό ν΄κ²°κ³Όμ
Main.storyboardμμ storyboardλ₯Ό κ΄λ¦¬νμ§ μκ³ , storyboard referenceλ₯Ό μ¬μ©νκ³ μμλ€.
κ·Έλ°λ° ν΄λΉ referenceλ₯Ό μ μΈν΄μ£Όμ§ μμμ self.storyboardμμ ν΄λΉ IDλ₯Ό μ°Ύμ μ μλ κ²μ΄μλ€.
κ·Έλμ storyboard referenceλ₯Ό λ€μ μ μΈν΄μ λ¬Έμ λ₯Ό ν΄κ²°νλ€. (pushλ‘ λ³΄μ¬μ€¬λ μ°κ²°μ λκ³ μμ νμλ€)
μΆκ°. μλ‘μ΄ λ€λΉκ²μ΄μ
μΌλ‘ μ΄λνλ λ°©λ²
// MARK: function
private func moveUserListViewController() {
let storyboard = UIStoryboard(name: "UserList", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "UserList") as! UserListViewController
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.modalPresentationStyle = .fullScreen
self.present(navigationController, animated: true, completion: nil)
}
// MARK: IBAction
@IBAction func didTappedSignInButton(_ sender: UIButton) {
guard let email = emailTextField.text,
let password = passwordTextField.text else { return }
Auth.auth().signIn(withEmail: email, password: password) { [weak self] result, error in
guard let strongSelf = self else { return }
if let error {
let alert = UIAlertController(title: "μ€λ₯", message: "μ€λ₯κ° λ°μνμ΅λλ€.", preferredStyle: .alert)
return
}
self?.moveUserListViewController()
}
}
Firestore
FIRInvalidArgumentException', reason: 'Unsupported type: __SwiftValue
μ±ν λ°©μ μμ±νκΈ° μν΄, μ°Έμ¬μλ₯Ό κΈ°μ€μΌλ‘ νμ¬ μ±ν λ°©μ΄ μ‘΄μ¬νλμ§, μ‘΄μ¬νμ§ μλμ§ νμΈνκΈ° μν΄ μ½λλ₯Ό μμ±νλ€.
κ·Έλμ usersμ [currentUser, tableViewμμ μ νν user]λ₯Ό κΈ°μ€μΌλ‘ chatroomμ μ‘΄μ¬νλ λ°©μ΄ μλμ§ μ½λλ₯Ό μμ±νλ€.
κ·Έλ°λ° FIRInvalidArgumentException', reason: 'Unsupported type: __SwiftValue μ΄ μλ¬κ° λ°μνλ€;;
κ²°λ‘ : λΉμ΄μλ collectionμ μ κ·ΌνκΈ° λλ¬Έμ΄λ€.
chatrooms collectionκ³Ό documentsκ° λͺ¨λ λΉμ΄μμλ€.
κ·Έλμ λ΄κ° μ μΈν codableλλ‘ λΉμ΄μλ λ°μ΄ν° νλλ₯Ό λ§λ€μ΄μ£Όλ μ‘°νκ° μ λλ€..... λ΄ μ½μ§...

Chatμ λ³νλ§ κ°μ§ν μ μμκΉ?
μ°μ μ μ¬μ§μμ λ³Ό μ μλ― λλ Chat Roomsλ₯Ό CollectionμΌλ‘ λ§λ€μλ€. μ¦, μ±ν μ΄ λ³νλ©΄, ChatRoomμ΄ λ³νκ² λλ κ²μ΄κ³ , κ·Έκ²μ λν κ²°κ³Όλ₯Ό 보μ¬μ€ λ€λ κ²μ΄λ€.
μ΄λ΄ λ μ΄λ€ λ¬Έμ κ° λ°μνλλ! λ³κ²½λ λ°μ΄ν°λ₯Ό κ°μ Έμμ tableviewλ₯Ό reloadν΄μ£ΌκΈ° λλ¬Έμ, μ 체 μ±ν μ΄ μλ‘κ³ μΉ¨λκ² λλ€. (λ°±λ¬ΈλΆμ¬μΌκ²¬ μμμ 보μ)
λ¬Έμ κ° λ μμ
λ¬Έμ κ° λ μ½λ
func setUpDataListener(id: String, completion: @escaping ([Chat]) -> Void) {
let reference = database.collection("chatRooms").document(id)
reference.addSnapshotListener {document, error in
guard let document, document.exists,
let chatData = document.data()?["chat"] as? [[String: Any]] else {
print("invalid format")
return
}
do {
let data = try JSONSerialization.data(withJSONObject: chatData, options: [])
let chats = try JSONDecoder().decode([Chat].self, from: data)
completion(chats)
} catch { }
}
}
referenceμΈ ChatRoomsμ snapshot Listnerλ₯Ό λ¬μλ€. κ·Έλμ Chatμ΄ μΆκ°λλ©΄, ChatRoomμ λ³νκ° κ°μ§λκ³ , κ·Έ κ²°κ³Ό chatDataμ ["chat"]μΌλ‘ μ€λ κ°λ€μ΄ μΆκ°λκ² λλ€ γ γ
ν΄κ²° λ°©λ²
쿼리μ listenerλ₯Ό λ¬μ보μ -> μ€ν¨.. (μ‘°κΈ λ 곡λΆν΄μΌκ² λ€)
listenerλ κ·Έλλ‘ λλ, View Controllerμμ μλ‘μ΄ λ°μ΄ν°λ₯Ό μΆμΆνλ λ°©μμΌλ‘ λ¬Έμ λ₯Ό ν΄κ²°νλ€.
κΈ°μ‘΄ μ½λ
private func setupChatDataListener() {
guard let chattingRoomID = chattingRoom?.uuid else { return }
ChatManager.shared.setUpDataListener(id: chattingRoomID) { [weak self] chats in
for chat in chats {
self?.chatDatas.append(chat)
let index = IndexPath(row: (self?.chatDatas.count ?? 0) - 1, section: 0)
self?.chattingTableView.insertRows(at: [index], with: .bottom)
self?.chattingTableView.scrollToRow(at: index, at: .bottom, animated: true)
}
}
}
κΈ°μ‘΄ μ½λμμλ μλ‘μ΄ λ°μ΄ν°λ₯Ό λͺ¨λ λΆλ¬μ€κ³ , κΈ°μ‘΄ Chat dataλ₯Ό μλ‘μ΄ λ°μ΄ν°λ‘ λ³κ²½νλ λ°©μμ μ¬μ©νμλ€. μμ μ λͺ°λμ§λ§ μ΄ μ½λ μ°λ©΄, A, B, Cκ° μμ λ μλ‘μ΄ Dκ° λ€μ΄μ¨λ€λ©΄ A, B, C, A, B, C, D μ΄λ°μμΌλ‘ λ°μ΄ν°κ° μ±ν λ°©μ λ¨μμμμ κ²μ΄λ€.
μλ‘μ΄ μ½λ
private func setupChatDataListener() {
guard let chattingRoomID = chattingRoom?.uuid else { return }
ChatManager.shared.setUpDataListener(id: chattingRoomID) { [weak self] chats in
var newChat = [Chat]()
for chat in chats {
newChat.append(chat)
}
newChat = (self?.filterNewChatting(newData: newChat, oldData: self?.chatDatas))!
self?.chatDatas.append(contentsOf: newChat)
self?.chattingTableView.reloadData()
let index = IndexPath(row: (self?.chatDatas.count ?? 1) - 1, section: 0)
self?.chattingTableView.scrollToRow(at: index, at: .bottom, animated: true)
}
}
private func filterNewChatting(newData: [Chat], oldData: [Chat]?) -> [Chat] {
guard let oldData = oldData else { return [] }
var newChat = [Chat]()
for chat in newData {
if !oldData.contains(chat) {
newChat.append(chat)
}
}
return newChat
}
κΈ°μ‘΄κ³Ό λμΌνκ² Chat Roomsμ μλ λͺ¨λ λ°μ΄ν°λ₯Ό νΈμΆνμ§λ§, filterNewChattingμ΄λΌλ ν¨μλ₯Ό λ§λ€μ΄μ κΈ°μ‘΄ μ±ν μ μλ μ±ν λ§ κ°μ Έμ€λλ‘ μμ νλ€.
μ΄λ₯Ό μν΄μλ Chat λͺ¨λΈμ Hashable νλ‘ν μ½μ μ¬μ©ν΄μΌνλ€. (containsλ₯Ό μ¬μ©νκΈ° μν΄μ)
Last updated