-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AI 챗봇 앱 [STEP 3] Jin, Harry #48
base: d_Jin
Are you sure you want to change the base?
Conversation
case chat | ||
} | ||
|
||
struct ChatRoomModel: Hashable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ChatRoomModel 은 좋지않은 이름입니다. 모든게 다 model아닌가요 ?
return label | ||
}() | ||
|
||
var outcoming = Role.user |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
적절한 이름인가요 ?
commonInit() | ||
} | ||
|
||
private func commonInit() -> Void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- layout을 잡는 코드같은데 왜 이름이 init인가요 ?
- -> Void의 용도는 무엇인가요 ?
]) | ||
} | ||
|
||
override func layoutSubviews() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
무엇을 해주는 메서드인가요 ?
import UIKit | ||
|
||
final class ChatRoomCell: UICollectionViewListCell { | ||
static let identifier = "ChatRoomCell" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다른방법은 없을까요?
|
||
private lazy var contentView = ChatRoomView() | ||
private let viewModel: ChatRoomViewModel | ||
private var bindings = Set<AnyCancellable>() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다른 레퍼런스에서도 이런 이름으로 쓰였던가요 ?
var snapshot = Snapshot() | ||
snapshot.appendSections([.chat]) | ||
snapshot.appendItems(viewModel.comments) | ||
dataSource.apply(snapshot, animatingDifferences: true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
contentView.collectionView.scrollToItem(at: index, at: .bottom, animated: true) 는 컴플리션에 달아주는게 나아보이네요.
} | ||
|
||
final class ChatRoomViewModel { | ||
@Published private(set) var comments: [ChatRoomModel] = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comments: [ChatRoomModel] 어색한 것 같습니다.
case chattingFetch | ||
} | ||
|
||
enum ChatRoomModelState: Equatable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋은 접근이네요.
ChatRoomVMState가 조금 더 나아보이네요.
} | ||
|
||
private func setupBindings() { | ||
func bindViewModelToView() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
중첩하신 이유가 있을까요 ?
안녕하세요 July(@July911), 진 해리입니다.
STEP3를 하는 동안 벚꽃이 다 지고 날이 점점 따듯해 지고 있는 것 같습니다.
우리의 앞길도 따듯해졌음 하는 작은 바람이 생깁니다.
처음으로 MVVM을 적용하기에 리팩토링이나, 역할 책임 분산이 다소 미흡합니다.
그렇지만 기능 구현은 되었다 생각하여 우여곡절 끝에 작업한 STEP3 PR 보내드립니다!
잘 부탁드리겠습니다. 😉
🔍 What is this PR?
ex) 처음에 API에게 이름을 말해주면, 대화 내내 API가 그 이름을 기억하고 말할 수 있다.
Core Graphics, Core Animation, UIView Animation 등을 사용해서 자유롭게 만들어주세요
KeyboardLayoutGuide를 활용해보세요.
문제가 발생할 경우, 사용자에게 알려준 후 다시 요청 할 수 있도록 구현해보세요.
🗂️ 아키텍처 및 기술스택
MVVM + Clean Architecture + Combine + UIKit
📝 PR 고민 Point
1. MVVM
Combine @published를 통해서 옵저빙이 가능하도록 뷰모델을 만들었습니다.
이후 ViewController를 뷰로 활용하여 바인딩을 통해 데이터의 상태가 변화하면 뷰가 업데이트 되도록 역할을 나누었습니다.
2. GPT 이전 대화 기록
history += "UserQuestion(count): (query)" + " "
history += "GPTAnswer(count): (answer[0].content)" + " "
위와 같이 history에 대화들을 계속 누적하게 만들어 대화형식으로 표현을 하고
질문을 할 때 history + question 형식으로 질문을 할 때 이전 대화 기록을 같이 보내 주는 방식으로 만들었습니다.
3. CollectionViewListCell Reusable
prepareForReuse를 활용하여 셀의 레이아웃 제약을 다시 그려줄 수 있도록 했습니다.
4. 말풍선
User질문과 GPT답변을 구분하여 레이아웃을 그려주는 방법은 아래와 같습니다.
viewModel.contentRole == .user 유저 메시지인지 아닌지에 따라 bubleView를 오른쪽 왼쪽으로 띄워줍니다.
5. 로딩창
시간 부족으로 애니메이션 관련된 부분은 우선 순위를 낮춰서 하여 말풍선이 로딩하는 것은 구현하지 못했지만 답변이 오는 동안 로딩 표시는 됩니다.
❓ 질문 Point
1. MVVM
인터넷에 예제를 참고하여서 처음으로 MVVM을 구현해봤습니다. 미흡한 부분이 많이 있을텐데 최대한 리뷰를 부탁드리며, ChatRoomCellViewMode에서 @published로 선언된 부분은 바인딩으로 사용되는 부분이 없는 것 같아 @published을 달아줄 필요가 없을 것 같은데... 예제에는 달려 있어서 남겨주었지만, 저희가 생각하고 있는 것이 맞는지 궁금합니다.
2. GPT 이전 대화 기록
현재의 방식은 질문에 이력을 추가해서 보내는 양식인데, 이런 이전 대화 기록 부분을 .system에 업데이트해서 관리하는 것이 더 나을지? 이전 대화 기록을 조금 더 잘 관리할 수 있는 부분이 궁금합니다.
3. 마지막에 발생한 GPT 이전 대화 기록 관련 버그
아래 history += "GPTAnswer(count): (answer[0].content)" + " "
가 한번만 호출되게 하고 싶은데 viewModel.$comments 이후로 안에 동작이 2번 이뤄집니다. 왜 두번 호출되는지 잘 모르겠습니다. 어떻게 디버깅을 해볼 수 있을까요?
📸 구동화면