Skip to content

Commit

Permalink
refactor/#404 버튼 클릭 시 POST API 연결 Rx 리팩토링
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaybei committed Dec 10, 2024
1 parent 2cf89fa commit e414948
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ final class SetReadyInfoViewController: BaseViewController {
super.viewDidLoad()
view.backgroundColor = .white

setupBinding()
setupTapGesture()
setupTextField()
bindViewModel()
Expand All @@ -69,20 +68,15 @@ final class SetReadyInfoViewController: BaseViewController {
setupTextField(textField: rootView.readyMinuteTextField)
setupTextField(textField: rootView.moveHourTextField)
setupTextField(textField: rootView.moveMinuteTextField)

rootView.doneButton.addTarget(
self,
action: #selector(doneButtonDidTap),
for: .touchUpInside
)
}

private func bindViewModel() {
let input = SetReadyInfoViewModel.Input(
readyHourText: rootView.readyHourTextField.rx.text.orEmpty.asObservable(),
readyMinuteText: rootView.readyMinuteTextField.rx.text.orEmpty.asObservable(),
moveHourText: rootView.moveHourTextField.rx.text.orEmpty.asObservable(),
moveMinuteText: rootView.moveMinuteTextField.rx.text.orEmpty.asObservable()
moveMinuteText: rootView.moveMinuteTextField.rx.text.orEmpty.asObservable(),
doneButtonDidTap: rootView.doneButton.rx.tap.asObservable()
)

let output = viewModel.transform(input: input, disposeBag: disposeBag)
Expand Down Expand Up @@ -123,6 +117,14 @@ final class SetReadyInfoViewController: BaseViewController {
owner.rootView.doneButton.isEnabled = isEnabled
}
.disposed(by: disposeBag)

output.isSucceed
.drive(with: self) { owner, isSucceed in
if isSucceed {
owner.navigateToSetReadyCompleted()
}
}
.disposed(by: disposeBag)
}

private func setupTextField(textField: UITextField) {
Expand All @@ -139,14 +141,17 @@ final class SetReadyInfoViewController: BaseViewController {
.disposed(by: disposeBag)
}

func showToast(_ message: String, bottomInset: CGFloat = 128) {
guard let view else { return }
Toast().show(message: message, view: view, position: .bottom, inset: bottomInset)
private func navigateToSetReadyCompleted() {
let setReadyCompletedViewController = SetReadyCompletedViewController()
self.navigationController?.pushViewController(
setReadyCompletedViewController,
animated: true
)
}

@objc
private func doneButtonDidTap(_ sender: UIButton) {
viewModel.updateReadyInfo()
private func showToast(_ message: String, bottomInset: CGFloat = 128) {
guard let view else { return }
Toast().show(message: message, view: view, position: .bottom, inset: bottomInset)
}


Expand Down Expand Up @@ -210,20 +215,4 @@ private extension SetReadyInfoViewController {
textField.accessibilityIdentifier = identifier
}
}

// MARK: - Data Bind

func setupBinding() {
viewModel.isSucceedToSave.bind { [weak self] _ in
if self?.viewModel.isSucceedToSave.value == true {
DispatchQueue.main.async {
let viewController = SetReadyCompletedViewController()
self?.navigationController?.pushViewController(
viewController,
animated: true
)
}
}
}
}
}
102 changes: 51 additions & 51 deletions KkuMulKum/Source/SetReadyInfo/ViewModel/SetReadyInfoViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,24 @@ final class SetReadyInfoViewModel {
let promiseName: String
let promiseTime: String

let isSucceedToSave = ObservablePattern<Bool>(false)

var errMessageRelay = PublishRelay<String>()
let errMessageRelay = PublishRelay<String>()
let isSucceedRelay = BehaviorRelay<Bool>(value: false)

let readyHourRelay = BehaviorRelay<String>(value: "")
let readyMinuteRelay = BehaviorRelay<String>(value: "")
let moveHourRelay = BehaviorRelay<String>(value: "")
let moveMinuteRelay = BehaviorRelay<String>(value: "")

var readyHour = ObservablePattern<String>("")
var readyMinute = ObservablePattern<String>("")
var moveHour = ObservablePattern<String>("")
var moveMinute = ObservablePattern<String>("")

var preparationTime = ObservablePattern<Int>(0)
var travelTime = ObservablePattern<Int>(0)

var storedReadyHour: Int = 0
var storedReadyMinute: Int = 0
var storedMoveHour: Int = 0
var storedMoveMinute: Int = 0

let bufferTime: TimeInterval = 10 * 60

var readyTime: Int = 0
var moveTime: Int = 0

let bufferTime: TimeInterval = 10 * 60

private let service: SetReadyStatusInfoServiceType
private let notificationManager: LocalNotificationManager

Expand All @@ -64,43 +55,6 @@ final class SetReadyInfoViewModel {
self.service = service
self.notificationManager = notificationManager
}

private func calculateTimes() {
let readyHours = Int(readyHour.value) ?? storedReadyHour
let readyMinutes = Int(readyMinute.value) ?? storedReadyMinute
let moveHours = Int(moveHour.value) ?? storedMoveHour
let moveMinutes = Int(moveMinute.value) ?? storedMoveMinute

readyTime = readyHours * 60 + readyMinutes
moveTime = moveHours * 60 + moveMinutes
}

func updateReadyInfo() {
calculateTimes()

// 로컬 알림 설정
scheduleLocalNotification()

Task {
let model = MyPromiseReadyInfoModel(
preparationTime: readyTime,
travelTime: moveTime
)

do {
guard let responseBody = try await service.updateMyPromiseReadyStatus(
with: promiseID,
requestModel: model
) else {
isSucceedToSave.value = false
return
}
isSucceedToSave.value = responseBody.success
} catch {
print(">>> \(error.localizedDescription) : \(#function)")
}
}
}
}

extension SetReadyInfoViewModel: ViewModelType {
Expand All @@ -109,6 +63,7 @@ extension SetReadyInfoViewModel: ViewModelType {
let readyMinuteText: Observable<String>
let moveHourText: Observable<String>
let moveMinuteText: Observable<String>
let doneButtonDidTap: Observable<Void>
}

struct Output {
Expand All @@ -118,6 +73,7 @@ extension SetReadyInfoViewModel: ViewModelType {
let moveMinuteText: Driver<String>
let errMessage: Driver<String>
let doneButtonIsEnabled: Driver<Bool>
let isSucceed: Driver<Bool>
}

func transform(input: Input, disposeBag: RxSwift.DisposeBag) -> Output {
Expand All @@ -141,6 +97,12 @@ extension SetReadyInfoViewModel: ViewModelType {
.bind(to: moveMinuteRelay)
.disposed(by: disposeBag)

input.doneButtonDidTap
.subscribe(with: self) { owner, _ in
owner.updateReadyInfo()
}
.disposed(by: disposeBag)

let readyHourText = checkValidTime(time: .hour, relay: readyHourRelay)
let readyMinuteText = checkValidTime(time: .minute, relay: readyMinuteRelay)
let moveHourText = checkValidTime(time: .hour, relay: moveHourRelay)
Expand All @@ -157,13 +119,16 @@ extension SetReadyInfoViewModel: ViewModelType {
.map { $0 && $1 && $2 && $3 }
.asDriver(onErrorJustReturn: false)

let isSucceed = isSucceedRelay.asDriver(onErrorJustReturn: false)

let output = Output(
readyHourText: readyHourText,
readyMinuteText: readyMinuteText,
moveHourText: moveHourText,
moveMinuteText: moveMinuteText,
errMessage: errMessage,
doneButtonIsEnabled: doneButtonIsEnabled
doneButtonIsEnabled: doneButtonIsEnabled,
isSucceed: isSucceed
)

return output
Expand All @@ -186,6 +151,41 @@ private extension SetReadyInfoViewModel {
}
.asDriver(onErrorJustReturn: "")
}

func calculateTotalTime() {
guard let readyHour = Int(readyHourRelay.value) else { return }
guard let readyMinute = Int(readyMinuteRelay.value) else { return }
guard let moveHour = Int(moveHourRelay.value) else { return }
guard let moveMinute = Int(moveMinuteRelay.value) else { return }

readyTime = readyHour * 60 + readyMinute
moveTime = moveHour * 60 + moveMinute
}

func updateReadyInfo() {
calculateTotalTime()
scheduleLocalNotification()

Task {
let model = MyPromiseReadyInfoModel(
preparationTime: readyTime,
travelTime: moveTime
)

do {
guard let responseBody = try await service.updateMyPromiseReadyStatus(
with: promiseID,
requestModel: model
) else {
isSucceedRelay.accept(false)
return
}
isSucceedRelay.accept(responseBody.success)
} catch {
print(">>> \(error.localizedDescription) : \(#function)")
}
}
}
}

private extension SetReadyInfoViewModel {
Expand Down

0 comments on commit e414948

Please sign in to comment.