가장 많은 시간을 할애했던 채팅기능 구현에 관해서 이야기해보고자 한다.
우선 채팅기능 구현은 파이어스토어를 통해서 진행하였다.
채팅기능 구현에서도 게시글 구현에서처럼 가장 어려웠던 부분은 컬렉션-문서-데이터필드으로 목록을 나워야하는데, 채팅방, 메세지, 유저 등등 나눠야할 하위목록도 너무 많았다. 그래서 3개로는 나누는 것을 굉장히 애를 먹다가 서브컬렉션이라는 것을 알게 되었다. 문서 하위에 데이터필드 대신에 서브 컬렉션으로 다시 서브 컬렉션-문서-데이터필드순으로 나열되게 되는 것이다.
우선 테이블 뷰의 형식으로 각 셀을 채팅방의 개념으로 구분하였다. 그리고 그 안에 다시 테이블 뷰 형식으로 셀이 채팅 내용인 개념이다. 테이블 뷰의 셀에 접근하기 위해선 익스텐션에서 접근할 필요가 있기때문에 주의가 필요하다.
자세한 코드는 생략하되,
var user1ValuesCount: Int = 0
var user1Values: [String] = [] // user1의 이메일을 저장할 배열
var user2Values: [String] = [] // user2의 이메일을 저장할 배열
var nickName: String?
var profileImage: UIImage?
var previewLabel: String?
var chatTime: String?
이런식으로 유저1, 유저2, 채팅방에 보여줄 마지막 대화, 프로필 사진, 닉네임 등등 미리 변수형태로 생성한 후, 저장한다.
let userEmail = UserDefaults.standard.string(forKey: "UserEmailKey")
let sortedEmails = [userEmail!, user].sorted()
let chatDocumentID = sortedEmails[0] + "&" + sortedEmails[1]
chatuser(상대방)을 받아온 후에 본인의 이메일과 순서에 상관없이 같은 채팅방으로 분류되게끔 하는 것이 중요했다. 만약 이 설정을 하지 않는다면 같은 사람과 채팅한 것이 두 개의 채팅방으로 나눠져 보인다.
채팅(컬렉션) - 유저1이메일 & 유저2이메일(문서) - 메세지(서브 컬렉션) - 무작위 문서 이름(문서) - 메세지 내용, 시간, 보내는사람(데이터필드)
이런식으로 정리했다.
채팅방은 이런식으로 프로필사진- 닉네임- 미리보기내용- 시간 이 나온다.
내부는 나가기 버튼, 상대의 닉네임, 프로필사진으로 심플하게 구성하였다.
힘들었던 부분은 각 셀마다 채팅방 및 대화내용 등 각각 표기해야하기때문에 그런것들을 표기해주는 로직을 구현하는게 까다로웠다.
그 외에도 채팅창 위로 키보드가 나와 가리게 되는 부분이라던가, 말풍선을 설정하는 부분, 하나하나 쉽지 않았다.
(실제 아이폰에서 구동한 화면)
그러나 이런 부분들은 잘 검색해보면 같은 고민을 한 사람들이 많아서 그래도 깔끔하게 해결할 수 있었으나 파이어베이스의 데이터 저장 방식은 아무리 찾아도 나오지 않아 스스로 발견해내고 구성하느라 많은 시간이 걸렸다.
코드를 썼다가 실패해서 다시 저장 방식을 변경하고를 수차례 반복하고 성공한 방식이다. 어디서 따라한 것이 아니라 스스로 방식을 세운거라 나중에 입사하게된다면 회사에선 어떤식으로 채팅 어플을 설계하는지 궁금하다.
다음엔 엑스코드에서 실제 아이폰 구동했던 과정에 대해서 적어야겠다.