Skip to content
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

[Feature] Implementation CoreData Behavior with View (User) Input Actions #39

Merged

Conversation

keeplo
Copy link
Contributor

@keeplo keeplo commented Aug 23, 2022

구현 배경

#33 RecordView 기능구현
close #34 ConversationUseCase 기능구현
close #38 NoteUseCase 기능 구현

기능 설명

공통 사항

  • Protocol 추상화로 인한 @published 변화
    @published 로 데이터 최신화를 하는 UseCase의 dataSource를,
    ViewModel에서 List 그려주는 @published 프로퍼티와 연결하는 작업
       protocol Maintainable {
          var dataSourcePublisher: Published<[Item]>.Publisher { get }
       }
    
       class UseCase: Maintainable {
            @Published private var dataSource: [Item] = []
            var dataSourcePublisher: Published<[Item]>.Publisher { $dataSource }
       }
    
       class ViewModel {
            @Published var list: [Conversation] = []
    
        init(dependency: Dependency) {
     	self.dependency = dependency
    
     	self.dependency.useCase.dataSourcePublisher
     		.assign(to: &self.$list)
          }
       }

Conversation

  • RecordView : Create 동작 구현
  • ConversationListView : Fetch List 연동 (@published) / Delete 동작 구현

Note

  • SelectionView : Create 동작 구현
  • NoteSet : Fetch List 연동 (@published) / Delete 동작 구현
  • NoteDetail : Update 동작 구현
  • NoteUseCase : isDone 연산프로퍼티로 입력여부 확인

UseCase 동작 이외에 수정

  • RecordView : Pin 찍기 기능 아이디어 적용
  • NoteDetailView : 취소 버튼 삭제 및 저장 버튼 disabled 기준 isEdited 구현
  • NoteSetViewRow : isDone 체크 -> TODO 리스트 형태 UI 체크
  • ConversationListRow : isChecked 체크 -> infomation 입력 여부 체크로 변경

Data Layer 수정사항

  • 다른 역할의 두 객체가 Repository 이름으로 겹치는 현상
    UseCase에서 다루는 Repository 용어의 객체 명칭 -> DataController 로 변경

    Local Repository에서 데이터를 불러오기 및 변경요청을 하는 객체로
    Domain Layer 에서 추상화된 DataController는 데이터 불러오기 및 변경요청을 담당

코멘트

  • 추가적인 회의를 거치지 않았지만.. 임의의로 DataController 명칭으로 변경하였습니다.

- 각 상황에 맞는 기능 메서드 구현 (ViewModel)
- pin 초기화 및 찍기, 제거 동작 구현
- CoreData에 저장 동작 (UseCase) 구현
- 테스트 용 코드 작성
- CoreData fetch 정렬 내림차순으로 변경
- UseCase DataSource  View에 바로 연동 되도록 Publish 동작 구현
- onDelete 와 연동해서 제거 동작 구현
- 사용자 입력 조건 체크하는 LanguageCheckable 프로토콜 extension 기능 구현
- 사용자 입력에 따라 Note 데이터 저장 기능 구현
- 오타 수정 sentece -> sentence
- PresentationDIContatiner 테스트 추가
- RecordViewModel UnitTest 구성
- SelectionViewModel UnitTest 구현
- Conversation List Published 연동
- Note List Published 연동
- Debug Repository Published protocol 연동
- 제거 동작 ViewModel로 이동
- Local Repository를 다루는 Controller 명칭 변경
   Repository -> DataController
- 사용자 입력 조건 체크하는 LanguageCheckable 프로토콜 extension 기능 구현
- 사용자 입력에 따라 Note 데이터 저장 기능 구현
- 오타 수정 sentece -> sentence
- Placeholder 수정 (기본 날짜, 안내문)
- CoreData 와 연동해서 Update 기능 구현
- NoteDetailView 취소 버튼 제거
- NoteDetailView 완료 버튼 -> 저장
- 저장 버튼 사용성 체크
- NoteSetRow 컨텐츠 onTapGesture 동작 이슈 해결 
- NoteUseCase edit(_:_:) 메서드 매개변수 수정
- 발음 관련 컨텐츠 삭제(MVP)
- isDone 연산프로퍼티로 TODO 상태 처리
- Info 입력시 Row 우측에 체크해주는 UI 구현
@keeplo keeplo added feature New feature or request refactor It'll be refactoring labels Aug 23, 2022
@keeplo keeplo requested a review from dacodaco August 23, 2022 08:37
@keeplo keeplo self-assigned this Aug 23, 2022
Comment on lines +23 to +26
public func hasTwoMoreSpace(by text: String) -> Bool {
let trimmedText = text.trimmingCharacters(in: [" "])
return trimmedText.components(separatedBy: " ").count > 2
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모듈화를 할거면, 파라미터로 스페이스 개수를 지정해서 검사할 수 있게 하면 어떨까요?!
hasSpaces(lessThan: Int) -> Bool

@@ -17,44 +17,46 @@ public protocol ConversationRecodable {
}

public protocol ConversationMaintainable {
var list: [Conversation] { get }
var dataSourcePublisher: Published<[Conversation]>.Publisher { get }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@published를 프로토콜에서 사용하겠다는 의지 잘 봤습니다...

}
fetcedList = dependency.dataController.fetch(filter: item) ?? []
}
self.dataSource = fetcedList.filter({ !$0.isDone }) + fetcedList.filter({ $0.isDone })
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CoreData에서 Fetch 해오는 시점에 바로 descending이 가능할 것 같은데,
성능적으로 무엇이 더 나은지까지는... 검사해봐야 알 것 같네요 ㅜㅜ
염두해봅시다.

@@ -60,7 +60,7 @@ extension ConversationListRow {
@ViewBuilder
private func CheckMarkIndicator() -> some View {
if viewModel.isChecked {
Image(systemName: "checkmark.circle.fill")
Image(systemName: "info.circle.fill")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presentation Layer 와 Data Layer 를 나눠서 Pull Request 보내는 습관을 들여봅시다!

@@ -19,21 +20,29 @@ final class ConversationListViewModel: Dependency, ObservableObject {

let dependency: Dependency

@Published var list: [Conversation] = []

private var cancellables: Set<AnyCancellable> = []
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assign(to:) 쓰시면 cancellables 필요 없어욥

.font(.headline)
.foregroundColor(.logoDarkGreen)
}
.disabled(!viewModel.isEdited)
.opacity(viewModel.isEdited ? 1 : 0.3)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disabled 활용하면 자동으로 불투명해지는 것으로 알고있는데 아닌가요?!

let newItem: Note = .init(
id: self.dependency.item.id,
original: self.original.trimmingCharacters(in: [" "]),
translation: self.translation.trimmingCharacters(in: [" "]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

??

Comment on lines 90 to 108
func addNote() -> Bool {
guard checkConditions() else { return false }
let newItem: Note = .init(
id: .init(),
original: language == .original ? self.inputText : "",
translation: language == .translation ? self.inputText : "",
category: category == .vocabulary ? .vocabulary : .sentence,
references: [self.dependency.item.id],
createdDate: Date()
)
self.dependency.noteUseCase.add(item: newItem) { error in
guard error == nil else {
print("add Note 실패") // TODO: Error 처리 필요
return
}
self.inputText = ""
}
return true
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프로퍼티에 isNoteAdded: Bool라고 넣어두고
함수 내부에서 Bool값을 변경하는 방식이 나은 것 같습니다!
함수명과 반환타입이 어색해요!

keeplo and others added 2 commits August 27, 2022 17:34
- isAbleToAdd 연산프로퍼티가 조건을 확인
- AddNote의 반환값 제거
@dacodaco dacodaco merged commit 421f967 into develop Aug 27, 2022
@keeplo keeplo deleted the feature-implementation_coredata_behavior_with_view_input branch September 18, 2022 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request refactor It'll be refactoring
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request] NoteUseCase 기능 구현 [Feature Request] Conversation UseCase 기능 구현
2 participants