diff --git a/KkuMulKum/Source/SetReadyInfo/ViewController/SetReadyInfoViewController.swift b/KkuMulKum/Source/SetReadyInfo/ViewController/SetReadyInfoViewController.swift index 960f072..10a3645 100644 --- a/KkuMulKum/Source/SetReadyInfo/ViewController/SetReadyInfoViewController.swift +++ b/KkuMulKum/Source/SetReadyInfo/ViewController/SetReadyInfoViewController.swift @@ -43,7 +43,6 @@ final class SetReadyInfoViewController: BaseViewController { super.viewDidLoad() view.backgroundColor = .white - setupBinding() setupTapGesture() setupTextField() bindViewModel() @@ -69,12 +68,6 @@ 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() { @@ -82,7 +75,8 @@ final class SetReadyInfoViewController: BaseViewController { 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) @@ -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) { @@ -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) } @@ -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 - ) - } - } - } - } } diff --git a/KkuMulKum/Source/SetReadyInfo/ViewModel/SetReadyInfoViewModel.swift b/KkuMulKum/Source/SetReadyInfo/ViewModel/SetReadyInfoViewModel.swift index 18707bd..651bcff 100644 --- a/KkuMulKum/Source/SetReadyInfo/ViewModel/SetReadyInfoViewModel.swift +++ b/KkuMulKum/Source/SetReadyInfo/ViewModel/SetReadyInfoViewModel.swift @@ -21,33 +21,24 @@ final class SetReadyInfoViewModel { let promiseName: String let promiseTime: String - let isSucceedToSave = ObservablePattern(false) - - var errMessageRelay = PublishRelay() + let errMessageRelay = PublishRelay() + let isSucceedRelay = BehaviorRelay(value: false) let readyHourRelay = BehaviorRelay(value: "") let readyMinuteRelay = BehaviorRelay(value: "") let moveHourRelay = BehaviorRelay(value: "") let moveMinuteRelay = BehaviorRelay(value: "") - - var readyHour = ObservablePattern("") - var readyMinute = ObservablePattern("") - var moveHour = ObservablePattern("") - var moveMinute = ObservablePattern("") - - var preparationTime = ObservablePattern(0) - var travelTime = ObservablePattern(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 @@ -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 { @@ -109,6 +63,7 @@ extension SetReadyInfoViewModel: ViewModelType { let readyMinuteText: Observable let moveHourText: Observable let moveMinuteText: Observable + let doneButtonDidTap: Observable } struct Output { @@ -118,6 +73,7 @@ extension SetReadyInfoViewModel: ViewModelType { let moveMinuteText: Driver let errMessage: Driver let doneButtonIsEnabled: Driver + let isSucceed: Driver } func transform(input: Input, disposeBag: RxSwift.DisposeBag) -> Output { @@ -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) @@ -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 @@ -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 {