EveryDiary - View Reload (1)

ulls12·2024년 3월 18일
0

Swift TIL

목록 보기
53/60

MVP 중간 점검이 끝나고, 지금까지 새로운 일기를 작성, 수정, 삭제를 한다거나 사용자가 로그인, 로그아웃, 회원탈퇴를 하게 될 경우 View의 데이터를 리로드하는 시점을 ViewWillApear에 때려박아놨었다. 그러다 보니, 리로드는 정말 기똥차게 처리하지만, 쓸데없이 불필요하게 데이터를 리로드하는 경우가 많아졌고, 일기의 갯수가 늘어날수록, 앱이 무거워지는 현상을 야기하게 되었다. 그래서 데이터를 로드하는 시점을 변경하는 작업이 필요했다.

리로드가 되는 시점 생각해보기

일기는 일기를 작성, 수정, 삭제 시에만 데이터 리로드가 필요하다. 그렇다는 건, 작성 완료 버튼을 누르거나, 수정 버튼을 눌러서 일기 데이터가 업데이트 되거나, 삭제 버튼을 눌러 데이터가 삭제가 되는 경우이다. 이럴 경우에 View에서는 데이터를 리로드하여 반영을 시켜줘야 한다. 그렇다면 어떤 방식으로 VC에 전달해주는 게 좋을까?

우선, 데이터가 리로드 될때, 추가적인 View Component의 요소가 바뀌지 않고, 오로지 일기 데이터만 리로드를 해달라고 부탁하면 되는 상황이기에 1대1 통신만으로도 충분하다. 또한 다른 새로운 VC가 추가되고 해당 VC에서도 써야하는 상황에서 유연하게 대처 가능한 방식을 써야한다고 판단했다.
그래서 Delegate 패턴을 쓰기로 결정했다.

Delegate 패턴 사용하기

Delegate 패턴을 사용하면 일기 작성 또는 수정 화면이 일기 목록 화면에 대한 명확한 참조를 갖게 되어, 변경된 데이터를 직접 전달할 수 있다. 이는 데이터 흐름을 추적하기 쉽게 하며, 누가 데이터를 전달하는지 명확하게 한다. 또한, 작성 또는 수정된 일기 내용을 목록 화면에 바로 반영할 수 있어, 사용자 경험을 개선한다.

  1. 프로토콜 설정
    protocol DiaryUpdateDelegate: AnyObject {
        func diaryDidUpdate()
    }
  1. delegate 변수 설정
    // WriteDiaryVC에서
    // 일기 작성하는 View에서 작성, 수정이 함께 일어난다
    weak var delegate: DiaryUpdateDelegate?
  1. 버튼이 누르고 작성 or 수정이 완료되는 부분에서 delegate 메서드를 호출
    func createAndUploadDiaryEntry(with title: String, content: String, dateString: String, imageUrls: [String] = []) {
        let newDiaryEntry = DiaryEntry(
            title: title,
            content: content,
            dateString: dateString,
            emotion: selectedEmotion,
            weather: selectedWeather,
            imageURL: imageUrls
        )
        
        // DiaryManager를 사용해 FireStore에 저장
        diaryManager.addDiary(diary: newDiaryEntry) { [weak self] error in
            guard let self = self else { return }
            self.isSavingDiary = false  // 성공, 실패 여부를 떠나서 저장 시도가 완료되었으므로 변수 초기화
            if let error = error {
                // 에러처리
                print("Error saving diary to Firestore: \(error.localizedDescription)")
            } else {
                // 에러가 없다면, 화면 닫기
                self.dismiss(animated: true, completion: nil)
                // delegate 설정하여 데이터 리로드
                self.delegate?.diaryDidUpdate()
            }
        }
    }
  1. 데이터 리로드가 필요한 VC에서 프롵토콜을 채택하고 메서드를 설정해준다.
// CalendarVC에서
//MARK: - 일기 데이터 수정 시, View Reload
extension CalendarVC: DiaryUpdateDelegate {
    func diaryDidUpdate() {
        loadDiaries()
        //데이터를 firebase에서 리로드하여 View를 업데이트 해주는 메서드
    }
}
  1. CalendarVC에서 작성 버튼을 눌렀을 때, 위임자 설정을 해준다.
    @objc private func tabWriteDiaryBTN() {
        let writeDiaryVC = WriteDiaryVC()
        writeDiaryVC.delegate = self
        writeDiaryVC.modalPresentationStyle = .automatic
        self.present(writeDiaryVC, animated: true)
    }

self를 delegate에 할당함으로써, 현재 인스턴스(즉, self가 가리키는 인스턴스)가 writeDiaryVC의 대리자(delegate) 역할을 수행하게 된다. 이는 writeDiaryVC가 일기 작성, 수정, 저장 등의 특정 작업을 완료했을 때, 이에 대한 응답을 처리하기 위한 메서드를 현재 클래스에서 구현하고 호출할 수 있음을 의미한다.

profile
I am 개발해요

0개의 댓글