( 작은 단위에 제한된 느낀점들임 )
우선 위에서 빨갛게 해놓은 작은 단위에 대한 설명부터 하기전에, 지금 하는 프로젝트의 특징을 먼저 나열해보겠다 !
- 서버 X, 데이터는 UserDefaults에 저장함.
- 로그인 기능 없음
- 위치 정보 확인함
- local notification을 활용할 예정
로그인 기능이 없기 때문에 마이 페이지도 없다. 그렇기 때문에 탭 3개 중 하나는 현재 앱 버전, 기본 알림 설정, 위치정보활용방침을 설정하거나 볼 수 있는 탭이다.
이 설정 탭을 구현하면서 이 프로젝트에 적용하기로 했던 것들(MVVM, Clean Architecture, RxSwift)을 적용해보면서 느낀점에 대해서 적어볼 예정이다 !
구현 화면은 아래와 같다 ! (UIView에 tap gesture를 넣어 rx.event 로 데이터를 넘겨주는 내용은 여기 ! )
보면 알겠지만 유저와 크게 상호작용을 해서 업데이트 된 데이터를 뷰에 적용 해준다거나 그럴 화면이 없다.
결국 Viewmodel의 output을 만들어서 view에 업데이트를 해줄 것이 없다는 것이다 !
왜 output이 없는 것에 밑줄을 치면서 이 글을 작성하게 되었을까 ?
그 이유는, 이 프로젝트에서 적용하기로 했던 아키텍쳐, 디자인 패턴이 이 설정의 부분에서 만큼은 오버 엔지니어링이라고 느껴졌기 때문이다.
ViewModel의 형태가 불편했던 이유
이 설정 리스트의 어떤 것을 선택하더라도 흐름이 이렇게 될텐데,
한 프로젝트 안에서 통일된 형태를 갖추기 위해 viewmodel의 input, output, func transform의 형태로 구현해야한다는게 불편했다.
Viewmodel의 형태를 in,output으로 구현했을 때의 코드는 이렇고,
// VM의 일부 코드
public func transform(input: Input) -> Output {
let output = Output()
input.defaultAlarmTapEvent
.withUnretained(self)
.subscribe(onNext: { viewModel, _ in
// 뷰 이동
viewModel.coordinator.setDefaultAlarm()
print("알람설정 tap")
})
.disposed(by: disposeBag)
input.termsTapEvent
.withUnretained(self)
.subscribe(onNext: { viewModel, _ in
viewModel.coordinator.presentTermsPrivacy()
print("이용약관 tap")
})
.disposed(by: disposeBag)
return output
}
extension SettingsViewModel {
public struct Input {
let defaultAlarmTapEvent: Observable<Void>
let termsTapEvent: Observable<Void>
}
public struct Output {
}
}
viewmodel의 형태를 in,output을 사용하지 않았더라면 이렇게 구현할 수 있었을 것 같다.
public func tapDefaultAlarmBtn() {
coordinator.setDefaultAlarm()
print("알람설정 tap")
}
public func tapTermsOfPrivacyBtn() {
coordinator.presentTermsPrivacy()
print("이용약관 tap")
}
8줄의 코드로 구현이 가능한데 구조를 맞추기 위해 필요한 코드들을 넣어 몇 배로 불려 작성한 코드.. 과연 좋은 프로그래밍인가 ?
라는 생각을 지울 수 없다.
물론 전체 프로젝트로 생각한다면
ViewModel의 형태를 Input, output, func transform으로 선택한 것도 데이터의 흐름이나 이 viewmodel을 사용하는 viewController에서 어떤 일이 일어날지 예측이 가능하다는 장점을 확실히 느낄 수 있어서 채택한 것에 대해 완전히 반대하는 것이 아니다 !
(장황하게 썼지만 이 viewmodel 새롭고 좋았다 ! )
'swift > swift 공부' 카테고리의 다른 글
UIImageView에 GIF 넣기 [Lottie 사용X] (3) | 2024.12.12 |
---|---|
protocol에서 associatedtype은 뭘까 ? (0) | 2024.08.08 |
[RxSwift] UIView에 tap event 추가하기 ( rx.event의 형태) (0) | 2024.02.15 |
Custom View Modifier 만들기 (0) | 2023.09.18 |