diff --git a/Koin/Core/View/BottomSheetViewControllerB.swift b/Koin/Core/View/BottomSheetViewControllerB.swift index fe91e6fb..524038ef 100644 --- a/Koin/Core/View/BottomSheetViewControllerB.swift +++ b/Koin/Core/View/BottomSheetViewControllerB.swift @@ -17,6 +17,7 @@ protocol BottomSheetViewControllerBDelegate: AnyObject { final class BottomSheetViewControllerB: UIViewController { // MARK: - Properties + private var contentViewBottomConstraint: Constraint? private var safeAreaHeightConstraint: Constraint? private var alpha: CGFloat @@ -54,7 +55,6 @@ final class BottomSheetViewControllerB: UIViewController { override func viewDidLoad() { super.viewDidLoad() configureView() - addObserver() setGesture() hideKeyboardWhenTappedAround() } @@ -69,33 +69,26 @@ final class BottomSheetViewControllerB: UIViewController { extension BottomSheetViewControllerB: BottomSheetViewControllerBDelegate { func present() { - contentView.snp.remakeConstraints { - $0.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom) - $0.leading.trailing.equalToSuperview() - } +// view.layoutIfNeeded() + contentViewBottomConstraint?.update(offset: 0) UIView.animate(withDuration: 0.25) { [weak self] in guard let self else { return } dimView.alpha = alpha - view.setNeedsLayout() view.layoutIfNeeded() } } func dismiss() { - contentView.snp.remakeConstraints { - $0.top.equalTo(view.snp.bottom) - $0.leading.trailing.equalToSuperview() - } + contentViewBottomConstraint?.update(offset: contentView.bounds.height) UIView.animate( withDuration: 0.25, animations: { [weak self] in guard let self else { return } dimView.alpha = 0 - view.setNeedsLayout() view.layoutIfNeeded() }, completion: { [weak self] _ in - self?.dismiss(animated: true) + self?.dismiss(animated: false) }) } } @@ -107,34 +100,10 @@ extension BottomSheetViewControllerB { dimView.addGestureRecognizer(tapGesture) } - private func addObserver() { - NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) - } - @objc private func dimViewTapped() { dismissKeyboard() dismiss() } - - @objc private func keyboardWillShow(_ notification: Notification) { - contentView.snp.remakeConstraints { - $0.bottom.equalTo(view.keyboardLayoutGuide.snp.top) - $0.leading.trailing.equalToSuperview() - } - UIView.animate(withDuration: 0.25) { [weak self] in - self?.view.layoutIfNeeded() - } - } - @objc private func keyboardWillHide(_ notification: Notification) { - contentView.snp.remakeConstraints { - $0.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom) - $0.leading.trailing.equalToSuperview() - } - UIView.animate(withDuration: 0.25) { [weak self] in - self?.view.layoutIfNeeded() - } - } } extension BottomSheetViewControllerB { @@ -155,7 +124,8 @@ extension BottomSheetViewControllerB { $0.edges.equalToSuperview() } contentView.snp.makeConstraints { - $0.top.equalTo(view.snp.bottom) + contentView.layoutIfNeeded() + contentViewBottomConstraint = $0.bottom.equalTo(view.keyboardLayoutGuide.snp.top).offset(contentView.bounds.height).constraint $0.leading.trailing.equalToSuperview() } safeAreaView.snp.makeConstraints { diff --git a/Koin/Core/View/KoinPickerDropDownView/Delegates/KoinPickerDropDownViewDateDelegate.swift b/Koin/Core/View/KoinPickerDropDownView/Delegates/KoinPickerDropDownViewDateDelegate.swift index ff2ea74e..19998a99 100644 --- a/Koin/Core/View/KoinPickerDropDownView/Delegates/KoinPickerDropDownViewDateDelegate.swift +++ b/Koin/Core/View/KoinPickerDropDownView/Delegates/KoinPickerDropDownViewDateDelegate.swift @@ -11,14 +11,12 @@ import Then final class KoinPickerDropDownViewDateDelegate { // MARK: - Properties - let columnWidths: [CGFloat] = [53, 31, 31] + private var dates: [Int: [Int: [Int]]] = [:] + private let columnWidths: [CGFloat] = [53, 31, 31] - private let inputFormatter = DateFormatter().then { - $0.dateFormat = "yyyy-MM-dd" - } - - private let outputFormatter = DateFormatter().then { - $0.dateFormat = "yyyy년*M월*d일" + // MARK: - Initialzier + init(range: Range) { + resetDates(range: range) } } @@ -29,68 +27,90 @@ extension KoinPickerDropDownViewDateDelegate: KoinPickerDropDownViewDelegate { } func reset(koinPicker: KoinPickerDropDownView, initialDate: Date) { + let year = initialDate.year + let month = initialDate.month + let day = initialDate.day - let selectedItem = outputFormatter.string(from: initialDate).components(separatedBy: "*") - let items = getItems(selectedItem: selectedItem) + let items = getItems(year: year, month: month) + let selectedItem: [String] = ["\(year)년", "\(month)월", "\(day)일"] - koinPicker.reset(items: items, selectedItem: selectedItem, columnWidths: [53, 31, 31]) + koinPicker.reset(items: items, selectedItem: selectedItem, columnWidths: columnWidths) } func selectedItemUpdated(koinPicker: KoinPickerDropDownView, selectedItem: [String]) { - guard let yearInt = Int(selectedItem[0].filter { $0.isNumber }), - let monthInt = Int(selectedItem[1].filter { $0.isNumber }), - var dayInt = Int(selectedItem[2].filter { $0.isNumber }) else { + guard let selectedYear = Int(selectedItem[0].filter { $0.isNumber }), + var selectedMonth = Int(selectedItem[1].filter { $0.isNumber }), + var selectedDay = Int(selectedItem[2].filter { $0.isNumber }) else { assert(false) return } - let maxDay = getAllDays(year: yearInt, month: monthInt).count - if dayInt > maxDay { - dayInt = maxDay + let items = getItems(year: selectedYear, month: selectedMonth) + guard let minMonthString = items[1].first?.filter({ $0.isNumber}), + let minMonth = Int(minMonthString), + let maxMonthString = items[1].last?.filter({ $0.isNumber}), + let maxMonth = Int(maxMonthString) else { + assert(false) + return } - guard let validDate = inputFormatter.date(from: String(format: "%d-%d-%d", yearInt, monthInt, dayInt)) else { + guard let minDayString = items[2].first?.filter({ $0.isNumber }), + let minDay = Int(minDayString), + let maxDayString = items[2].last?.filter({ $0.isNumber }), + let maxDay = Int(maxDayString) else { assert(false) return } - reset(koinPicker: koinPicker, initialDate: validDate) + selectedMonth = min(max(selectedMonth, minMonth), maxMonth) + selectedDay = min(max(selectedDay, minDay), maxDay) + let selectedItem: [String] = ["\(selectedYear)년", "\(selectedMonth)월", "\(selectedDay)일"] + koinPicker.reset(items: items, selectedItem: selectedItem, columnWidths: columnWidths) } } extension KoinPickerDropDownViewDateDelegate { - private func getItems(selectedItem: [String]) -> [[String]] { - - guard let selectedYearInt = Int(selectedItem[0].filter { $0.isNumber }), - let selectedMonthInt = Int(selectedItem[1].filter { $0.isNumber }) else { - assert(false) - return [[],[],[]] + private func resetDates(range: Range) { + let calendar = Calendar.current + let startDay = calendar.startOfDay(for: Date()) + let availableDates = range.compactMap { + calendar.date(byAdding: .day, value: $0, to: startDay) } - let years: [String] = { - let thisYearInt = Date().year - let lowestYearInt = min(selectedYearInt, thisYearInt) - let heighestYearInt = thisYearInt + 1 - return Range(lowestYearInt...heighestYearInt).map { String($0)+"년" } - }() - let months: [String] = Range(1...12).map { String($0)+"월" } - let days: [String] = getAllDays(year: selectedYearInt, month: selectedMonthInt) + var dates: [Int: [Int: [Int]]] = [:] - return [years, months, days] + for date in availableDates { + if dates[date.year] == nil { + dates[date.year] = [:] + } + + if dates[date.year]?[date.month] == nil { + dates[date.year]?[date.month] = [] + } + + dates[date.year]?[date.month]?.append(date.day) + } + + self.dates = dates } - func getAllDays(year: Int, month: Int) -> [String] { - - let calendar = Calendar.current - var components = DateComponents() - components.year = year - components.month = month + private func getItems(year: Int, month: Int) -> [[String]] { + guard let minYear: Int = dates.keys.sorted().first, + let maxYear: Int = dates.keys.sorted().last else { + assert(false) + return [[],[],[]] + } + let year = min(max(minYear, year), maxYear) - guard let date = calendar.date(from: components), - let dayRange = calendar.range(of: .day, in: .month, for: date) else { + guard let minMonth: Int = dates[year]?.keys.sorted().first, + let maxMonth: Int = dates[year]?.keys.sorted().last else { assert(false) - return [] + return [[],[],[]] } + let month = min(max(minMonth, month), maxMonth) - return dayRange.map { String($0) + "일" } + let years: [String] = dates.keys.sorted().map { "\($0)년" } + let months: [String] = dates[year]!.keys.sorted().map { "\($0)월" } + let days: [String] = dates[year]![month]!.sorted().compactMap { "\($0)일" } + return [years, months, days] } } diff --git a/Koin/Data/DTOs/Decodable/CallVan/CallVanDataDto.swift b/Koin/Data/DTOs/Decodable/CallVan/CallVanDataDto.swift index 78f26fda..b798bf41 100644 --- a/Koin/Data/DTOs/Decodable/CallVan/CallVanDataDto.swift +++ b/Koin/Data/DTOs/Decodable/CallVan/CallVanDataDto.swift @@ -95,7 +95,7 @@ extension CallVanDataDto { formatter.dateFormat = "yyyy-MM-dd" formatter.locale = Locale(identifier: "ko_KR") if let date = formatter.date(from: departureDate) { - formatter.dateFormat = "MM.dd (a)" + formatter.dateFormat = "MM.dd (E)" return formatter.string(from: date) } else { return departureDate diff --git a/Koin/Presentation/CallVan/CallVanChat/CallVanChatViewModel.swift b/Koin/Presentation/CallVan/CallVanChat/CallVanChatViewModel.swift index fbd8f353..930cba7a 100644 --- a/Koin/Presentation/CallVan/CallVanChat/CallVanChatViewModel.swift +++ b/Koin/Presentation/CallVan/CallVanChat/CallVanChatViewModel.swift @@ -125,7 +125,11 @@ extension CallVanChatViewModel { private func fetchData() { fetchCallVanDataUseCase.execute(postId: postId).sink( - receiveCompletion: { _ in }, + receiveCompletion: { [weak self] comepltion in + if case .failure(let error) = comepltion { + self?.outputSubject.send(.showToast(error.message)) + } + }, receiveValue: { [weak self] callVanData in self?.outputSubject.send(.updateData(callVanData)) } diff --git a/Koin/Presentation/CallVan/CallVanData/CallVanDataViewController.swift b/Koin/Presentation/CallVan/CallVanData/CallVanDataViewController.swift index 9180f9af..eefc9a96 100644 --- a/Koin/Presentation/CallVan/CallVanData/CallVanDataViewController.swift +++ b/Koin/Presentation/CallVan/CallVanData/CallVanDataViewController.swift @@ -68,6 +68,8 @@ extension CallVanDataViewController { participantsTableView.configure(participants: callVanData.participants) case let .updateBell(alert): configureRightBarButton(alert: alert) + case let .showToast(message): + showToastMessage(message: message) } refreshControl.endRefreshing() }.store(in: &subscriptions) diff --git a/Koin/Presentation/CallVan/CallVanData/CallVanDataViewModel.swift b/Koin/Presentation/CallVan/CallVanData/CallVanDataViewModel.swift index 20694af9..0d74c419 100644 --- a/Koin/Presentation/CallVan/CallVanData/CallVanDataViewModel.swift +++ b/Koin/Presentation/CallVan/CallVanData/CallVanDataViewModel.swift @@ -13,6 +13,7 @@ final class CallVanDataViewModel: ViewModelProtocol { enum Output { case update(CallVanData) case updateBell(alert: Bool) + case showToast(String) } enum Input { case viewWillAppear @@ -64,7 +65,11 @@ extension CallVanDataViewModel { private func fetchData() { fetchCallVanDataUseCase.execute(postId: postId).sink( - receiveCompletion: { _ in }, + receiveCompletion: { [weak self] completion in + if case .failure(let error) = completion { + self?.outputSubject.send(.showToast(error.message)) + } + }, receiveValue: { [weak self] callVanData in self?.outputSubject.send(.update(callVanData)) } @@ -73,7 +78,11 @@ extension CallVanDataViewModel { private func fetchNotification() { fetchCallVanNotificationListUseCase.execute().sink( - receiveCompletion: { _ in }, + receiveCompletion: { [weak self] completion in + if case .failure(let error) = completion { + self?.outputSubject.send(.showToast(error.message)) + } + }, receiveValue: { [weak self] notifications in let alert = notifications.filter { !$0.isRead }.count != 0 self?.outputSubject.send(.updateBell(alert: alert)) diff --git a/Koin/Presentation/CallVan/CallVanList/CallVanListViewModel.swift b/Koin/Presentation/CallVan/CallVanList/CallVanListViewModel.swift index b5af2e38..69bbda38 100644 --- a/Koin/Presentation/CallVan/CallVanList/CallVanListViewModel.swift +++ b/Koin/Presentation/CallVan/CallVanList/CallVanListViewModel.swift @@ -129,7 +129,11 @@ extension CallVanListViewModel { private func fetchNotification() { fetchCallVanNotificationListUseCase.execute().sink( - receiveCompletion: { _ in }, + receiveCompletion: { [weak self] completion in + if case .failure(let error) = completion { + self?.outputSubject.send(.showToast(error.message)) + } + }, receiveValue: { [weak self] notifications in let alert = notifications.filter { !$0.isRead }.count != 0 self?.outputSubject.send(.updateBell(alert: alert)) diff --git a/Koin/Presentation/CallVan/CallVanPost/CallVanPostViewModel.swift b/Koin/Presentation/CallVan/CallVanPost/CallVanPostViewModel.swift index 52b450d9..ab890b2f 100644 --- a/Koin/Presentation/CallVan/CallVanPost/CallVanPostViewModel.swift +++ b/Koin/Presentation/CallVan/CallVanPost/CallVanPostViewModel.swift @@ -37,7 +37,7 @@ final class CallVanPostViewModel: ViewModelProtocol { } private(set) var request = CallVanPostRequest() { didSet { - validateRequest() + validate() } } @@ -98,13 +98,42 @@ extension CallVanPostViewModel { outputSubject.send(.updateArrival(request.arrivalType, request.arrivalCustomName)) } - private func validateRequest() { - let validation = request.departureType != nil - && request.arrivalType != nil - && request.departureDate != nil - && request.departureTime != nil + private func validate() { + var isValid = true - outputSubject.send(.enablePostButton(validation)) + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd HH:mm" + let tenMinutes: TimeInterval = 1 * 60 * 10 + + /// 빈 값이 있는지 확인 + if request.departureType == nil + || request.arrivalType == nil + || request.departureDate?.isEmpty == true + || request.departureTime?.isEmpty == true { + isValid = false + } + + /// 출발지와 도착지가 다른지 확인 + switch (request.departureType, request.arrivalType) { + case (.custom, .custom): + if request.departureCustomName == request.arrivalCustomName { + isValid = false + } + default: + if request.departureType == request.arrivalType { + isValid = false + } + } + + /// 현재 시각으로부터 최소 10분 이후 일정인지 확인 + let date = request.departureDate ?? "" + let time = request.departureTime ?? "" + if let requestDate = formatter.date(from: "\(date) \(time)"), + requestDate.timeIntervalSince(Date()) < tenMinutes { + isValid = false + } + + outputSubject.send(.enablePostButton(isValid)) } private func postData() { diff --git a/Koin/Presentation/CallVan/CallVanPost/Subviews/CallVanPostDateView.swift b/Koin/Presentation/CallVan/CallVanPost/Subviews/CallVanPostDateView.swift index 2b705e65..dae08cbf 100644 --- a/Koin/Presentation/CallVan/CallVanPost/Subviews/CallVanPostDateView.swift +++ b/Koin/Presentation/CallVan/CallVanPost/Subviews/CallVanPostDateView.swift @@ -25,7 +25,7 @@ final class CallVanPostDateView: ExtendedTouchAreaView { private let dateButton = UIButton() private let dateLabel = UILabel() private let downArrowImageView = UIImageView() - private let dateDropDownView = KoinPickerDropDownView(delegate: KoinPickerDropDownViewDateDelegate()) + private let dateDropDownView = KoinPickerDropDownView(delegate: KoinPickerDropDownViewDateDelegate(range: 0..<365)) // MARK: - Initializer init() { diff --git a/Koin/Presentation/CallVan/CallVanPost/Subviews/CallVanPostPlaceBottomSheetView.swift b/Koin/Presentation/CallVan/CallVanPost/Subviews/CallVanPostPlaceBottomSheetView.swift index 8cc46867..4ca69235 100644 --- a/Koin/Presentation/CallVan/CallVanPost/Subviews/CallVanPostPlaceBottomSheetView.swift +++ b/Koin/Presentation/CallVan/CallVanPost/Subviews/CallVanPostPlaceBottomSheetView.swift @@ -65,33 +65,30 @@ final class CallVanPostPlaceBottomSheetView: UIView { onApplyButtonTapped: @escaping (CallVanPlace, String?)->Void ) { self.onApplyButtonTapped = onApplyButtonTapped - + titleLabel.text = title.rawValue - + + resetState() + if place == .custom { (buttons1 + buttons2).forEach { $0.isSelected = false } customButton.isSelected = true customPlaceTextField.text = customPlace - customPlaceTextField.snp.remakeConstraints { - $0.height.equalTo(47) - $0.top.equalTo(separatorView.snp.bottom).offset(24) - $0.leading.trailing.equalToSuperview().inset(32) - } - applyButton.setAttributedTitle(NSAttributedString( - string: "입력완료", - attributes: [ - .font : UIFont.appFont(.pretendardBold, size: 16), - .foregroundColor : UIColor.appColor(.neutral0) - ]), for: .normal - ) + updateCustomPlaceTextField(isVisible: true) + updateApplyButtonTitle(isCustomSelected: true) + valiate(customPlaceTextField) } else { let place = place ?? CallVanPlace.frontGate (buttons1 + buttons2).forEach { - $0.isSelected = $0.filterState as! CallVanPlace == place + $0.isSelected = $0.filterState as? CallVanPlace == place } customButton.isSelected = false + updateCustomPlaceTextField(isVisible: false) + updateApplyButtonTitle(isCustomSelected: false) + applyButton.backgroundColor = UIColor.appColor(.new500) + applyButton.isEnabled = true } } required init?(coder: NSCoder) { @@ -126,12 +123,8 @@ extension CallVanPostPlaceBottomSheetView { } } customButton.isSelected = false - - customPlaceTextField.snp.remakeConstraints { - $0.height.equalTo(0) - $0.top.equalTo(separatorView.snp.bottom).offset(0) - $0.leading.trailing.equalToSuperview().inset(32) - } + + updateCustomPlaceTextField(isVisible: false) UIView.animate( withDuration: 0.2, animations: { [weak self] in @@ -139,14 +132,7 @@ extension CallVanPostPlaceBottomSheetView { self?.layoutIfNeeded() self?.applyButton.isEnabled = true self?.applyButton.backgroundColor = UIColor.appColor(.new500) - self?.applyButton.do { - $0.setAttributedTitle(NSAttributedString( - string: "선택하기", - attributes: [ - .font : UIFont.appFont(.pretendardBold, size: 16), - .foregroundColor : UIColor.appColor(.neutral0) - ]), for: .normal) - } + self?.updateApplyButtonTitle(isCustomSelected: false) }, completion: { [weak self] _ in self?.customPlaceTextField.resignFirstResponder() @@ -159,26 +145,14 @@ extension CallVanPostPlaceBottomSheetView { $0.isSelected = false } sender.isSelected = true - - customPlaceTextField.snp.remakeConstraints { - $0.height.equalTo(47) - $0.top.equalTo(separatorView.snp.bottom).offset(24) - $0.leading.trailing.equalToSuperview().inset(32) - } + + updateCustomPlaceTextField(isVisible: true) UIView.animate( withDuration: 0.2, animations: { [weak self] in self?.superview?.layoutIfNeeded() self?.layoutIfNeeded() - self?.applyButton.do { - $0.setAttributedTitle(NSAttributedString( - string: "입력완료", - attributes: [ - .font : UIFont.appFont(.pretendardBold, size: 16), - .foregroundColor : UIColor.appColor(.neutral0) - ]), for: .normal) - } - + self?.updateApplyButtonTitle(isCustomSelected: true) }, completion: { [weak self] _ in self?.customPlaceTextField.becomeFirstResponder() @@ -190,16 +164,14 @@ extension CallVanPostPlaceBottomSheetView { if let selectedButton = (buttons1 + buttons2).first(where: { $0.isSelected }), let selectedPlace = selectedButton.filterState as? CallVanPlace { onApplyButtonTapped?(selectedPlace, nil) - customPlaceTextField.resignFirstResponder() - delegate?.dismiss() } else if customButton.isSelected, let customPlace = customPlaceTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines), !customPlace.isEmpty { onApplyButtonTapped?(.custom, customPlace) - customPlaceTextField.resignFirstResponder() - delegate?.dismiss() } + customPlaceTextField.resignFirstResponder() + delegate?.dismiss() } } @@ -231,6 +203,38 @@ extension CallVanPostPlaceBottomSheetView: UITextFieldDelegate { } extension CallVanPostPlaceBottomSheetView { + + private func resetState() { + (buttons1 + buttons2).forEach { + $0.isSelected = false + } + customButton.isSelected = false + customPlaceTextField.text = nil + customPlaceTextField.resignFirstResponder() + updateCustomPlaceTextField(isVisible: false) + updateApplyButtonTitle(isCustomSelected: false) + applyButton.backgroundColor = UIColor.appColor(.new500) + applyButton.isEnabled = true + } + + private func updateCustomPlaceTextField(isVisible: Bool) { + customPlaceTextField.snp.remakeConstraints { + $0.height.equalTo(isVisible ? 47 : 0) + $0.top.equalTo(separatorView.snp.bottom).offset(isVisible ? 24 : 0) + $0.leading.trailing.equalToSuperview().inset(32) + } + } + + private func updateApplyButtonTitle(isCustomSelected: Bool) { + let title = isCustomSelected ? "입력완료" : "선택하기" + applyButton.setAttributedTitle(NSAttributedString( + string: title, + attributes: [ + .font : UIFont.appFont(.pretendardBold, size: 16), + .foregroundColor : UIColor.appColor(.neutral0) + ]), for: .normal + ) + } private func configureView() { setUpStyles() diff --git a/Koin/Presentation/Home/Home/HomeViewController.swift b/Koin/Presentation/Home/Home/HomeViewController.swift index 5d428213..eaaef88d 100644 --- a/Koin/Presentation/Home/Home/HomeViewController.swift +++ b/Koin/Presentation/Home/Home/HomeViewController.swift @@ -176,6 +176,7 @@ final class HomeViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + inputSubject.send(.checkLogin) inputSubject.send(.getUserScreenAction(Date(), .enterVC)) inputSubject.send(.getUserScreenAction(Date(), .beginEvent, .mainShopCategories)) inputSubject.send(.categorySelected(getDiningPlace())) diff --git a/Koin/Presentation/Home/Home/HomeViewModel.swift b/Koin/Presentation/Home/Home/HomeViewModel.swift index 6ef88d5e..bef4556d 100644 --- a/Koin/Presentation/Home/Home/HomeViewModel.swift +++ b/Koin/Presentation/Home/Home/HomeViewModel.swift @@ -22,6 +22,7 @@ final class HomeViewModel: ViewModelProtocol { case getUserScreenAction(Date, ScreenActionType, EventParameter.EventLabelNeededDuration? = nil) case getNoticeBanner(Date?) case fetchBanner + case checkLogin case logSessionEvent(EventLabelType, EventParameter.EventCategory, Any, String) } @@ -85,7 +86,6 @@ final class HomeViewModel: ViewModelProtocol { input.sink { [weak self] input in switch input { case .viewDidLoad: - self?.checkLogin() self?.getShopCategory() self?.checkVersion() self?.fetchUserData() @@ -103,6 +103,8 @@ final class HomeViewModel: ViewModelProtocol { self?.getNoticeBanners(date: date) case .fetchBanner: self?.fetchBanner() + case .checkLogin: + self?.checkLogin() case let .logEventDirect(name, label, value, category): self?.logAnalyticsEventUseCase.logEvent(name: name, label: label, value: value, category: category) case let .logSessionEvent(label, category, value, sessionId):