RxSwift๋ฅผ ํ™œ์šฉํ•ด View - ViewModel์„ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๊ณผ์ •์—์„œ View์˜ ๋‹ค์–‘ํ•œ Input๋“ค์„ ์กฐํ•ฉ / ๋ณ€ํ™˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. ์—ฌ๊ธฐ์„œ Observable์„ ์—ฌ๋Ÿฌ๋ฒˆ ๊ตฌ๋…์‹œํ‚ค๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ, ์ฝ”๋“œ ์ž‘์„ฑ ์‹œ ์ง์ ‘ ๊ฒช์—ˆ๋˜ ๋ฌธ์ œ๋ฅผ ํ†ตํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๊ณ  ์ฃผ์˜์‚ฌํ•ญ์„ ๊ธฐ๋กํ•˜๊ณ ์ž ํ•œ๋‹ค.

๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋˜ ์ฝ”๋“œ

// ViewModel

struct Input {
    let title: Driver<String>
    let date: Driver<Date>
    let body: Driver<String>
    let rightBarButtonTapped: Driver<Void>
    let leftBarButtonTapped: Driver<Void>
}
    
struct Output {
    let canSave: Driver<Bool>
    let save: Observable<Void>
    let canEdit: Driver<Bool>
    let dismiss: Driver<Void>
}

func transform(_ input: Input) -> Output {
    let projectContents = Driver.combineLatest(input.title, 
																							 input.date, 
																							 input.body)
        
    let canSave = projectContents
        .map { title, _, body in
            return title != "" || body != ""
        }
        .asDriver(onErrorJustReturn: false)
    
// ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ Observable
    let save = input.rightBarButtonTapped
        .asObservable()
        .withLatestFrom(projectContents)
        .map { title, date, body in
            return Contents(title: title,
                            date: date,
                            body: body,
                            id: UUID())
        }
        .map { [unowned self] project in
            try useCase.create(project: project)
            delegate?.projectCreated()
        }
    
    let canEdit = Driver.just(true)
    
    let dismiss = Driver.merge(input.leftBarButtonTapped,
                               projectSave.asDriver(onErrorJustReturn: ()))
        .do(onNext: navigator.toMain)
    
    return Output(canSave: canSave,
                  save: projectSave,
                  canEdit: canEdit,
                  dismiss: dismiss)
}

ViewModel์˜ Input์€ ์ฐจ๋ก€๋กœ ์„ค๋ช…ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

์œ„ ์ฝ”๋“œ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋˜ ๋ถ€๋ถ„์€ save ์ด๋‹ค.

save๋Š” ์˜ค๋ฅธ์ชฝ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ” ๋ฒ„ํŠผ์˜ tap ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐ๋กœ ํ•˜์—ฌ view์—์„œ ๋ฐ›์•„์˜จ Input์„ useCase๋ฅผ ํ†ตํ•ด DB์— ์ €์žฅํ•˜๋Š” ์ŠคํŠธ๋ฆผ์ด๋‹ค.

dismiss ์˜ ๊ฒฝ์šฐ ์™ผ์ชฝ, ์˜ค๋ฅธ์ชฝ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ” ๋ฒ„ํŠผ์˜ tap ์ด๋ฒคํŠธ๋ฅผ mergeํ•˜์—ฌ ํ™”๋ฉด์„ dismissํ•˜๋Š” ์ŠคํŠธ๋ฆผ์ด๋‹ค.

๋‘ ์ŠคํŠธ๋ฆผ์€ ๋ชจ๋‘ Output์œผ๋กœ ๋ฐ˜ํ™˜๋˜์–ด ViewController์—์„œ ๊ตฌ๋…์ด ์ผ์–ด๋‚œ๋‹ค.


๐Ÿ”Žย ๋ฌธ์ œ์ 