diff --git a/KkuMulKum.xcodeproj/project.pbxproj b/KkuMulKum.xcodeproj/project.pbxproj index 42e35e9e..155a9e89 100644 --- a/KkuMulKum.xcodeproj/project.pbxproj +++ b/KkuMulKum.xcodeproj/project.pbxproj @@ -190,6 +190,7 @@ DE159D332C406E1600425101 /* MyPageContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE159D2B2C406E1600425101 /* MyPageContentView.swift */; }; DE159D342C406E1600425101 /* MyPageEtcSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE159D2C2C406E1600425101 /* MyPageEtcSettingView.swift */; }; DE159D362C406E1600425101 /* MyPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE159D2F2C406E1600425101 /* MyPageViewController.swift */; }; + DE1917772CCB6B7300279D91 /* AddPromiseRequestModelBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE1917762CCB6B7300279D91 /* AddPromiseRequestModelBuilder.swift */; }; DE254AA82C3118EA00A4015E /* UIView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE254AA72C3118EA00A4015E /* UIView+.swift */; }; DE254AAA2C31190E00A4015E /* UIStackView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE254AA92C31190E00A4015E /* UIStackView+.swift */; }; DE254AAC2C31192400A4015E /* UILabel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE254AAB2C31192400A4015E /* UILabel+.swift */; }; @@ -405,6 +406,7 @@ DE159D2B2C406E1600425101 /* MyPageContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyPageContentView.swift; sourceTree = ""; }; DE159D2C2C406E1600425101 /* MyPageEtcSettingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyPageEtcSettingView.swift; sourceTree = ""; }; DE159D2F2C406E1600425101 /* MyPageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyPageViewController.swift; sourceTree = ""; }; + DE1917762CCB6B7300279D91 /* AddPromiseRequestModelBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddPromiseRequestModelBuilder.swift; sourceTree = ""; }; DE254AA72C3118EA00A4015E /* UIView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+.swift"; sourceTree = ""; }; DE254AA92C31190E00A4015E /* UIStackView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+.swift"; sourceTree = ""; }; DE254AAB2C31192400A4015E /* UILabel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+.swift"; sourceTree = ""; }; @@ -1352,6 +1354,14 @@ path = MyPage; sourceTree = ""; }; + DE1917752CCB6B6000279D91 /* Model */ = { + isa = PBXGroup; + children = ( + DE1917762CCB6B7300279D91 /* AddPromiseRequestModelBuilder.swift */, + ); + path = Model; + sourceTree = ""; + }; DE254AA12C31106700A4015E /* Application */ = { isa = PBXGroup; children = ( @@ -1651,6 +1661,7 @@ DECB844E2C43FB200022A003 /* AddPromise */ = { isa = PBXGroup; children = ( + DE1917752CCB6B6000279D91 /* Model */, DECB84522C43FB510022A003 /* ServiceType */, DECB84512C43FB400022A003 /* ViewModel */, DECB844F2C43FB300022A003 /* ViewController */, @@ -1929,6 +1940,7 @@ 782B40822C3E4925008B0CA7 /* NicknameViewModel.swift in Sources */, A3FB18592C3BF77D001483E5 /* MeetingInfoResponseModel.swift in Sources */, DD3466532C7B044F00E62284 /* ChooseMemberViewController.swift in Sources */, + DE1917772CCB6B7300279D91 /* AddPromiseRequestModelBuilder.swift in Sources */, DEA932182C3F180800FDF637 /* MeetingPromisesModel.swift in Sources */, DE159D342C406E1600425101 /* MyPageEtcSettingView.swift in Sources */, DE9E18842C3BA84500DB76B4 /* CustomTextField.swift in Sources */, diff --git a/KkuMulKum/Source/AddPromise/Model/AddPromiseRequestModelBuilder.swift b/KkuMulKum/Source/AddPromise/Model/AddPromiseRequestModelBuilder.swift new file mode 100644 index 00000000..d4017631 --- /dev/null +++ b/KkuMulKum/Source/AddPromise/Model/AddPromiseRequestModelBuilder.swift @@ -0,0 +1,101 @@ +// +// AddPromiseRequestModelBuilder.swift +// KkuMulKum +// +// Created by 김진웅 on 10/25/24. +// + +import Foundation + +extension AddPromiseRequestModel { + final class Builder { + private(set) var id = 0 + private var name = "" + private var placeName = "" + private var address = "" + private var roadAddress = "" + private var time = "" + private var dressUpLevel = "" + private var penalty = "" + private var x = 0.0 + private var y = 0.0 + private var participants = [Int]() + + @discardableResult + func setName(_ name: String) -> Self { + self.name = name + return self + } + + @discardableResult + func setPlaceName(_ placeName: String) -> Self { + self.placeName = placeName + return self + } + + @discardableResult + func setAddress(_ address: String) -> Self { + self.address = address + return self + } + + @discardableResult + func setRoadAddress(_ roadAddress: String) -> Self { + self.roadAddress = roadAddress + return self + } + + @discardableResult + func setTime(_ time: String) -> Self { + self.time = time + return self + } + + @discardableResult + func setDressUpLevel(_ dressUpLevel: String) -> Self { + self.dressUpLevel = dressUpLevel + return self + } + + @discardableResult + func setPenalty(_ penalty: String) -> Self { + self.penalty = penalty + return self + } + + @discardableResult + func setCoordinates(x: Double, y: Double) -> Self { + self.x = x + self.y = y + return self + } + + @discardableResult + func setId(_ id: Int) -> Self { + self.id = id + return self + } + + @discardableResult + func setParticipants(_ participants: [Int]) -> Self { + self.participants = participants + return self + } + + func build() -> AddPromiseRequestModel { + return AddPromiseRequestModel( + name: name, + placeName: placeName, + address: address, + roadAddress: roadAddress, + time: time, + dressUpLevel: dressUpLevel, + penalty: penalty, + x: x, + y: y, + id: id, + participants: participants + ) + } + } +} diff --git a/KkuMulKum/Source/AddPromise/ViewController/AddPromiseViewController.swift b/KkuMulKum/Source/AddPromise/ViewController/AddPromiseViewController.swift index 75e60e8e..5dce8246 100644 --- a/KkuMulKum/Source/AddPromise/ViewController/AddPromiseViewController.swift +++ b/KkuMulKum/Source/AddPromise/ViewController/AddPromiseViewController.swift @@ -9,15 +9,13 @@ import UIKit import RxCocoa import RxSwift -import SnapKit -import Then final class AddPromiseViewController: BaseViewController { - let rootView = AddPromiseView() private let viewModel: AddPromiseViewModel - private let disposeBag = DisposeBag() private let promiseNameTextFieldEndEditingRelay = PublishRelay() private let searchPlaceCompleted = PublishRelay() + private let disposeBag = DisposeBag() + private let rootView = AddPromiseView() // MARK: - Intializer @@ -93,24 +91,6 @@ final class AddPromiseViewController: BaseViewController { owner.navigationController?.pushViewController(viewController, animated: true) } .disposed(by: disposeBag) - - rootView.confirmButton.rx.tap - .map { _ in } - .subscribe(with: self) { owner, _ in - guard let place = owner.viewModel.place else { return } - - let viewController = SelectMemberViewController( - viewModel: SelectMemberViewModel( - meetingID: owner.viewModel.meetingID, - name: owner.viewModel.name, - place: place, - promiseDateString: owner.viewModel.combinedDateTime, - service: PromiseService() - ) - ) - owner.navigationController?.pushViewController(viewController, animated: true) - } - .disposed(by: disposeBag) } override func setupDelegate() { @@ -132,7 +112,6 @@ extension AddPromiseViewController: FindPlaceViewControllerDelegate { // MARK: - UITextFieldDelegate extension AddPromiseViewController: UITextFieldDelegate { - /// done을 눌렀을 때 func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField == rootView.promiseNameTextField { textField.resignFirstResponder() @@ -154,7 +133,8 @@ private extension AddPromiseViewController { promiseTextFieldEndEditing: promiseTextFieldEndEditing, date: rootView.datePicker.rx.date.asObservable(), time: rootView.timePicker.rx.date.asObservable(), - place: searchPlaceCompleted + place: searchPlaceCompleted.asObservable(), + confirmButtonDidTap: rootView.confirmButton.rx.tap.asObservable() ) let output = viewModel.transform(input: input, disposeBag: disposeBag) @@ -176,6 +156,18 @@ private extension AddPromiseViewController { owner.rootView.datePicker.date = date } .disposed(by: disposeBag) + + output.navigateToSelectMember + .subscribe(with: self) { owner, builder in + let viewController = SelectMemberViewController( + viewModel: SelectMemberViewModel( + builder: builder, + service: PromiseService() + ) + ) + owner.navigationController?.pushViewController(viewController, animated: true) + } + .disposed(by: disposeBag) } func configurePromiseName(result: TextFieldVailidationResult) { diff --git a/KkuMulKum/Source/AddPromise/ViewController/SelectMemberViewController.swift b/KkuMulKum/Source/AddPromise/ViewController/SelectMemberViewController.swift index 3131e8be..36d2134a 100644 --- a/KkuMulKum/Source/AddPromise/ViewController/SelectMemberViewController.swift +++ b/KkuMulKum/Source/AddPromise/ViewController/SelectMemberViewController.swift @@ -12,11 +12,9 @@ import RxSwift final class SelectMemberViewController: BaseViewController { private let viewModel: SelectMemberViewModel + private let viewWillAppearRelay = PublishRelay() private let disposeBag = DisposeBag() private let rootView = SelectMemberView() - private let viewWillAppearRelay = PublishRelay() - private let memberSelected = PublishSubject() - private let memberDeselected = PublishSubject() // MARK: - Initializer @@ -46,51 +44,20 @@ final class SelectMemberViewController: BaseViewController { bindViewModel() } - - override func setupAction() { - rootView.confirmButton.rx.tap - .subscribe(with: self) { owner, _ in - let viewController = SelectPenaltyViewController( - viewModel: SelectPenaltyViewModel( - meetingID: owner.viewModel.meetingID, - name: owner.viewModel.name, - place: owner.viewModel.place, - dateString: owner.viewModel.promiseDateString, - members: owner.viewModel.selectedMembers, - service: PromiseService() - ) - ) - owner.navigationController?.pushViewController(viewController, animated: true) - } - .disposed(by: disposeBag) - } - - override func setupDelegate() { - rootView.memberListView.delegate = self - } -} - - -// MARK: - UICollectionViewDelegate - -extension SelectMemberViewController: UICollectionViewDelegate { - func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - let selectedMember = viewModel.members[indexPath.item] - memberSelected.onNext(selectedMember) - } - - func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { - let deselectedMember = viewModel.members[indexPath.item] - memberDeselected.onNext(deselectedMember) - } } private extension SelectMemberViewController { func bindViewModel() { + let memberSelected = rootView.memberListView.rx.itemSelected + .map { $0.item } + let memberDeselected = rootView.memberListView.rx.itemDeselected + .map { $0.item } + let input = SelectMemberViewModel.Input( viewDidLoad: .just(()), memberSelected: memberSelected.asObservable(), - memberDeselected: memberDeselected.asObservable() + memberDeselected: memberDeselected.asObservable(), + confirmButtonDidTap: rootView.confirmButton.rx.tap.asObservable() ) let output = viewModel.transform(input: input, disposeBag: disposeBag) @@ -111,5 +78,17 @@ private extension SelectMemberViewController { owner.rootView.emptyContentView.isHidden = !flag } .disposed(by: disposeBag) + + output.navigateToSelectPenalty + .subscribe(with: self) { owner, builder in + let viewController = SelectPenaltyViewController( + viewModel: SelectPenaltyViewModel( + builder: builder, + service: PromiseService() + ) + ) + owner.navigationController?.pushViewController(viewController, animated: true) + } + .disposed(by: disposeBag) } } diff --git a/KkuMulKum/Source/AddPromise/ViewController/SelectPenaltyViewController.swift b/KkuMulKum/Source/AddPromise/ViewController/SelectPenaltyViewController.swift index c58ddcdc..e25e1ac2 100644 --- a/KkuMulKum/Source/AddPromise/ViewController/SelectPenaltyViewController.swift +++ b/KkuMulKum/Source/AddPromise/ViewController/SelectPenaltyViewController.swift @@ -12,10 +12,10 @@ import RxSwift final class SelectPenaltyViewController: BaseViewController { private let viewModel: SelectPenaltyViewModel - private let disposeBag = DisposeBag() - private let rootView = SelectPenaltyView() private let selectedLevelButtonRelay = BehaviorRelay(value: "") private let selectedPenaltyButtonRelay = BehaviorRelay(value: "") + private let disposeBag = DisposeBag() + private let rootView = SelectPenaltyView() // MARK: - Initializer @@ -88,10 +88,10 @@ private extension SelectPenaltyViewController { .disposed(by: disposeBag) output.isSucceedToCreate - .drive(with: self) { owner, result in - let (flag, promiseID) = result - guard flag else { return } - let viewController = AddPromiseCompleteViewController(promiseID: promiseID ?? 0) + .drive(with: self) { owner, promiseID in + guard promiseID > 0 else { return } + + let viewController = AddPromiseCompleteViewController(promiseID: promiseID) owner.navigationController?.pushViewController(viewController, animated: true) } .disposed(by: disposeBag) diff --git a/KkuMulKum/Source/AddPromise/ViewModel/AddPromiseViewModel.swift b/KkuMulKum/Source/AddPromise/ViewModel/AddPromiseViewModel.swift index ead0693f..e606a4a4 100644 --- a/KkuMulKum/Source/AddPromise/ViewModel/AddPromiseViewModel.swift +++ b/KkuMulKum/Source/AddPromise/ViewModel/AddPromiseViewModel.swift @@ -15,15 +15,7 @@ enum TextFieldVailidationResult { } final class AddPromiseViewModel { - let meetingID: Int - - var name: String { nameRelay.value } - var place: Place? { placeRelay.value } - var combinedDateTime: String { combinedDateTimeRelay.value } - - private let nameRelay = BehaviorRelay(value: "") - private let combinedDateTimeRelay = BehaviorRelay(value: "") - private let placeRelay = BehaviorRelay(value: nil) + private let meetingID: Int init(meetingID: Int) { self.meetingID = meetingID @@ -36,19 +28,19 @@ extension AddPromiseViewModel: ViewModelType { let promiseTextFieldEndEditing: Observable let date: Observable let time: Observable - let place: PublishRelay + let place: Observable + let confirmButtonDidTap: Observable } struct Output { let validationPromiseNameResult: Observable let isEnabledConfirmButton: Observable let adjustedDate: Observable + let navigateToSelectMember: Observable } func transform(input: Input, disposeBag: DisposeBag) -> Output { - input.promiseNameText - .bind(to: nameRelay) - .disposed(by: disposeBag) + let placeRelay = BehaviorRelay(value: nil) let isValid = input.promiseNameText .map { [weak self] text in @@ -61,7 +53,9 @@ extension AddPromiseViewModel: ViewModelType { let validationResultWhileEditing = input.promiseNameText .map { [weak self] text -> TextFieldVailidationResult in - guard let self else { return .basic } + guard let self else { + return .basic + } if text.isEmpty { return .basic @@ -84,12 +78,10 @@ extension AddPromiseViewModel: ViewModelType { validationResultWhileEditing, validationResultAfterEditing ) - Observable.combineLatest(input.date, input.time) + let combinedDateTime = Observable.combineLatest(input.date, input.time) .map { [weak self] date, time -> String in return self?.combine(date: date, time: time) ?? "" } - .bind(to: combinedDateTimeRelay) - .disposed(by: disposeBag) input.place .bind(to: placeRelay) @@ -115,10 +107,34 @@ extension AddPromiseViewModel: ViewModelType { return date } + let navigateToSelectMember = input.confirmButtonDidTap + .withLatestFrom( + Observable.combineLatest( + input.promiseNameText, + combinedDateTime, + input.place + ) + ) + .compactMap { [weak self] name, time, place -> AddPromiseRequestModel.Builder? in + guard let self else { + return nil + } + + return AddPromiseRequestModel.Builder() + .setId(meetingID) + .setName(name) + .setTime(time) + .setPlaceName(place.location) + .setAddress(place.address ?? "") + .setRoadAddress(place.roadAddress ?? "") + .setCoordinates(x: place.x, y: place.y) + } + return Output( validationPromiseNameResult: validationPromiseNameResult, isEnabledConfirmButton: isEnabledConfirmButton, - adjustedDate: adjustedDate + adjustedDate: adjustedDate, + navigateToSelectMember: navigateToSelectMember ) } } diff --git a/KkuMulKum/Source/AddPromise/ViewModel/SelectMemberViewModel.swift b/KkuMulKum/Source/AddPromise/ViewModel/SelectMemberViewModel.swift index 8564483c..c6016676 100644 --- a/KkuMulKum/Source/AddPromise/ViewModel/SelectMemberViewModel.swift +++ b/KkuMulKum/Source/AddPromise/ViewModel/SelectMemberViewModel.swift @@ -11,29 +11,15 @@ import RxCocoa import RxSwift final class SelectMemberViewModel { - let meetingID: Int - let name: String - let place: Place - let promiseDateString: String - - var members: [Member] { memberListRelay.value } - var selectedMembers: [Member] { selectedMemberListRelay.value } - + private let builder: AddPromiseRequestModel.Builder private let service: SelectMemeberServiceType private let memberListRelay = BehaviorRelay<[Member]>(value: []) - private let selectedMemberListRelay = BehaviorRelay<[Member]>(value: []) init( - meetingID: Int, - name: String, - place: Place, - promiseDateString: String, + builder: AddPromiseRequestModel.Builder, service: SelectMemeberServiceType ) { - self.meetingID = meetingID - self.name = name - self.place = place - self.promiseDateString = promiseDateString + self.builder = builder self.service = service } } @@ -41,15 +27,19 @@ final class SelectMemberViewModel { extension SelectMemberViewModel: ViewModelType { struct Input { let viewDidLoad: Observable - let memberSelected: Observable - let memberDeselected: Observable + let memberSelected: Observable + let memberDeselected: Observable + let confirmButtonDidTap: Observable } struct Output { let memberList: Driver<[Member]> + let navigateToSelectPenalty: Observable } func transform(input: Input, disposeBag: DisposeBag) -> Output { + let selectedMemberListRelay = BehaviorRelay<[Member]>(value: []) + input.viewDidLoad .subscribe(with: self) { owner, _ in owner.fetchMeetingMembers() @@ -57,25 +47,39 @@ extension SelectMemberViewModel: ViewModelType { .disposed(by: disposeBag) input.memberSelected - .subscribe(with: self) { owner, member in - var selectedMembers = owner.selectedMemberListRelay.value - guard !selectedMembers.contains(where: { $0.memberID == member.memberID }) else { return } - selectedMembers.append(member) - owner.selectedMemberListRelay.accept(selectedMembers) + .subscribe(with: self) { owner, selectedItem in + guard selectedItem < owner.memberListRelay.value.count else { return } + let selectedMember = owner.memberListRelay.value[selectedItem] + + var selectedMembers = selectedMemberListRelay.value + guard !selectedMembers.contains(where: { $0.memberID == selectedMember.memberID }) else { return } + selectedMembers.append(selectedMember) + selectedMemberListRelay.accept(selectedMembers) } .disposed(by: disposeBag) input.memberDeselected - .subscribe(with: self) { owner, member in - var selectedMembers = owner.selectedMemberListRelay.value - guard selectedMembers.contains(where: { $0.memberID == member.memberID }) else { return } - selectedMembers.removeAll { $0.memberID == member.memberID } - owner.selectedMemberListRelay.accept(selectedMembers) + .subscribe(with: self) { owner, deselectedItem in + guard deselectedItem < owner.memberListRelay.value.count else { return } + let deselectedMember = owner.memberListRelay.value[deselectedItem] + + var selectedMembers = selectedMemberListRelay.value + guard selectedMembers.contains(where: { $0.memberID == deselectedMember.memberID }) else { return } + selectedMembers.removeAll { $0.memberID == deselectedMember.memberID } + selectedMemberListRelay.accept(selectedMembers) } .disposed(by: disposeBag) + let navigateToSelectPenalty = input.confirmButtonDidTap + .withLatestFrom(selectedMemberListRelay) + .compactMap { [weak self] selectedMembers in + return self?.builder + .setParticipants(selectedMembers.map { $0.memberID }) + } + let output = Output( - memberList: memberListRelay.asDriver(onErrorJustReturn: []) + memberList: memberListRelay.asDriver(onErrorJustReturn: []), + navigateToSelectPenalty: navigateToSelectPenalty ) return output @@ -86,7 +90,7 @@ private extension SelectMemberViewModel { func fetchMeetingMembers() { Task { do { - guard let responseBody = try await service.fetchMeetingMemberListExcludeLoginUser(with: meetingID), + guard let responseBody = try await service.fetchMeetingMemberListExcludeLoginUser(with: builder.id), responseBody.success else { memberListRelay.accept([]) diff --git a/KkuMulKum/Source/AddPromise/ViewModel/SelectPenaltyViewModel.swift b/KkuMulKum/Source/AddPromise/ViewModel/SelectPenaltyViewModel.swift index dda93e25..df8f8d51 100644 --- a/KkuMulKum/Source/AddPromise/ViewModel/SelectPenaltyViewModel.swift +++ b/KkuMulKum/Source/AddPromise/ViewModel/SelectPenaltyViewModel.swift @@ -11,30 +11,15 @@ import RxCocoa import RxSwift final class SelectPenaltyViewModel { - let meetingID: Int - let name: String - let place: Place - let dateString: String - let members: [Member] - + private let builder: AddPromiseRequestModel.Builder private let service: SelectPenaltyServiceType - private let levelRelay = BehaviorRelay(value: "") - private let penaltyRelay = BehaviorRelay(value: "") private let newPromiseRelay = BehaviorRelay(value: nil) init( - meetingID: Int, - name: String, - place: Place, - dateString: String, - members: [Member], + builder: AddPromiseRequestModel.Builder, service: SelectPenaltyServiceType ) { - self.meetingID = meetingID - self.name = name - self.place = place - self.dateString = dateString - self.members = members + self.builder = builder self.service = service } } @@ -48,7 +33,7 @@ extension SelectPenaltyViewModel: ViewModelType { struct Output { let isEnabledConfirmButton: Observable - let isSucceedToCreate: Driver<(Bool, Int?)> + let isSucceedToCreate: Driver } func transform(input: Input, disposeBag: DisposeBag) -> Output { @@ -56,28 +41,26 @@ extension SelectPenaltyViewModel: ViewModelType { input.selectedLevelButton, input.selectedPenaltyButton ).map { !$0.isEmpty && !$1.isEmpty } - input.selectedLevelButton - .bind(to: levelRelay) - .disposed(by: disposeBag) - - input.selectedPenaltyButton - .bind(to: penaltyRelay) - .disposed(by: disposeBag) - input.confirmButtonDidTap - .subscribe(with: self) { owner, _ in - owner.requestAddNewPromise() + .withLatestFrom( + Observable.combineLatest( + input.selectedLevelButton, + input.selectedPenaltyButton + ) + ) + .subscribe(with: self) { [weak self] owner, values in + let (level, penalty) = values + self?.builder + .setDressUpLevel(level) + .setPenalty(penalty) + + self?.requestAddNewPromise() } .disposed(by: disposeBag) let isSucceedToCreate = newPromiseRelay - .map { promise -> (Bool, Int?) in - guard let promise else { - return (false, nil) - } - return (true, promise.promiseID) - } - .asDriver(onErrorJustReturn: (false, nil)) + .compactMap { $0?.promiseID } + .asDriver(onErrorJustReturn: -1) let output = Output( isEnabledConfirmButton: isEnabledConfirmButton, @@ -89,30 +72,12 @@ extension SelectPenaltyViewModel: ViewModelType { } private extension SelectPenaltyViewModel { - func createAddPromiseModel() -> AddPromiseRequestModel { - let addPromiseModel = AddPromiseRequestModel( - name: name, - placeName: place.location, - address: place.address ?? "", - roadAddress: place.roadAddress ?? "", - time: dateString, - dressUpLevel: levelRelay.value, - penalty: penaltyRelay.value, - x: place.x, - y: place.y, - id: meetingID, - participants: members.map { $0.memberID } - ) - - return addPromiseModel - } - func requestAddNewPromise() { Task { do { guard let responseBody = try await service.requestAddingNewPromise( - with: createAddPromiseModel(), - meetingID: meetingID + with: builder.build(), + meetingID: builder.id ), responseBody.success else {