Protocol 구현하기 - Model

SteadySlower·2022년 9월 22일
0
post-custom-banner

이전까지 Service들을 Protocol로 구현해보았습니다. 이제는 Model들을 Protocol로 구현해보도록 하겠습니다.

Protocol 구현하기

model은 상대적으로 아주 쉽습니다. let으로 선언하는 property들은 getter만 정의하고 var로 선언해서 재할당할 property들은 setter도 정의해주어야 합니다.

아래 Word의 경우 Firebase에서 디코딩할 때 기본값을 주기 위해서 var로 선언하기는 했습니다만 (자세한 이유는 이 포스팅 참고해주세요!) 한번 디코딩되고 나면 다시 set하지 않을 값이기 때문에 getter만 정의했습니다.

반면에 studyState의 경우 사용자가 업데이트하면 바뀌어야 하는 값이기 때문에 setter도 정의해줍니다.

computed property인 hasImage의 경우 get만 가능하므로 당연히 set은 정의하지 않습니다.

protocol Word {
    var id: String? { get }
    var wordBookID: String? { get set }
    var meaningText: String { get }
    var meaningImageURL: String { get }
    var ganaText: String { get }
    var ganaImageURL: String { get }
    var kanjiText: String { get }
    var kanjiImageURL: String { get }
    var studyState: StudyState { get set }
    var timestamp: Timestamp { get }
    var hasImage: Bool { get }
}

struct WordImpl: Word, Codable, Hashable{
    @DocumentID var id: String?
    var wordBookID: String?
    var meaningText: String = ""
    var meaningImageURL: String = ""
    var ganaText: String = ""
    var ganaImageURL: String = ""
    var kanjiText: String = ""
    var kanjiImageURL: String = ""
    var studyState: StudyState
    let timestamp: Timestamp
    
    var hasImage: Bool {
        !self.meaningImageURL.isEmpty || !self.ganaImageURL.isEmpty || !self.kanjiImageURL.isEmpty
    }
}

SwiftUI에서 사용할 때 주의할 점

TextEditor나 TextField처럼 값을 수정할 수 있는 View들은 Binding으로 전달되는 property에 setter가 구현되어 있어야 합니다!

TextEditor(text: $viewModel.word.meaningText)
profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.
post-custom-banner

0개의 댓글