-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] #578 - 코스퀘스트 탐험 인증 구현 #581
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Offroad-iOS/Offroad-iOS/Presentation/CourseQuest/Components/CourseQuestPlaceCell.swift
Outdated
Show resolved
Hide resolved
Offroad-iOS/Offroad-iOS/Network/CourseQuest/DTO/Response/CourseQuestDetailResponseDTO.swift
Outdated
Show resolved
Hide resolved
Offroad-iOS/Offroad-iOS/Presentation/CourseQuest/Components/CourseQuestPopUp.swift
Show resolved
Hide resolved
Offroad-iOS/Offroad-iOS/Presentation/CourseQuest/Components/CourseQuestPopUp.swift
Show resolved
Hide resolved
Offroad-iOS/Offroad-iOS/Presentation/CourseQuest/Components/CourseQuestPopUp.swift
Outdated
Show resolved
Hide resolved
Offroad-iOS/Offroad-iOS/Presentation/CourseQuest/Components/CourseQuestPopUp.swift
Outdated
Show resolved
Hide resolved
...oad-iOS/Offroad-iOS/Presentation/CourseQuest/ViewControllers/CourseQuestViewController.swift
Outdated
Show resolved
Hide resolved
...oad-iOS/Offroad-iOS/Presentation/CourseQuest/ViewControllers/CourseQuestViewController.swift
Outdated
Show resolved
Hide resolved
| cell.onVisit = { [weak self] in | ||
| self?.courseQuestPlaces[indexPath.item] = CourseQuestDetailPlaceDTO( | ||
| category: quest.category, | ||
| name: quest.name, | ||
| address: quest.address, | ||
| latitude: quest.latitude, | ||
| longitude: quest.longitude, | ||
| isVisited: true, | ||
| categoryImage: quest.categoryImage, | ||
| description: quest.description, | ||
| placeId: quest.placeId | ||
| ) | ||
| collectionView.reloadItems(at: [indexPath]) | ||
| self?.showToast("방문 성공! 앞으로 N곳 남았어요") | ||
| guard let self else { return } | ||
| let place = quest | ||
|
|
||
| guard let currentCoordinate = locationManager.location?.coordinate else { return } | ||
|
|
||
| // 변수 먼저 선언 | ||
| var requestDTO: AdventuresPlaceAuthenticationRequestDTO | ||
|
|
||
| // 개발자 모드의 설정값 중 '탐험 시 위치 인증 무시' 값에 따라 분기 처리 | ||
| let locationAuthenticationBypassing = UserDefaults.standard.bool(forKey: "bypassLocationAuthentication") | ||
| if locationAuthenticationBypassing { | ||
| requestDTO = AdventuresPlaceAuthenticationRequestDTO( | ||
| placeId: place.placeId, | ||
| latitude: place.latitude, | ||
| longitude: place.longitude | ||
| ) | ||
| } else { | ||
| requestDTO = AdventuresPlaceAuthenticationRequestDTO( | ||
| placeId: place.placeId, | ||
| latitude: currentCoordinate.latitude, | ||
| longitude: currentCoordinate.longitude | ||
| ) | ||
| } | ||
|
|
||
| Task { | ||
| do { | ||
| let result = try await AdventureService().authenticateAdventurePlace(adventureAuthDTO: requestDTO) | ||
|
|
||
| switch (result.isValidPosition, result.isFirstVisitToday) { | ||
| case (true, true): | ||
| // 탐험 성공 | ||
| self.courseQuestPlaces[indexPath.item] = CourseQuestDetailPlaceDTO( | ||
| category: place.category, | ||
| name: place.name, | ||
| address: place.address, | ||
| latitude: place.latitude, | ||
| longitude: place.longitude, | ||
| isVisited: true, | ||
| categoryImage: place.categoryImage, | ||
| description: place.description, | ||
| placeId: place.placeId | ||
| ) | ||
| self.currentCount += 1 | ||
| //남은 탐험 수 | ||
| let remainCount = max(self.totalCount - self.currentCount, 0) | ||
| collectionView.reloadItems(at: [indexPath]) | ||
| await MainActor.run { | ||
| if remainCount == 0 { | ||
| CourseQuestPopUp.showPopUp( | ||
| on: self.view, | ||
| message: "퀘스트 클리어! 보상을 받아보세요" | ||
| ) { | ||
| $0.highlightText(targetText: "보상", font: .offroad(style: .iosTextBold)) | ||
| } | ||
| } else { | ||
| CourseQuestPopUp.showPopUp( | ||
| on: self.view, | ||
| message: "방문 성공! 앞으로 \(remainCount)곳 남았어요" | ||
| ) { | ||
| $0.highlightText(targetText: "\(remainCount)곳", font: .offroad(style: .iosTextBold)) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| default: | ||
| // 위치 인증 실패 → ORBAlertController 사용 | ||
| let message = AlertMessage.courseQuestFailureLocationMessage | ||
| let buttonTitle = "확인" | ||
|
|
||
| await MainActor.run { | ||
| let alertController = ORBAlertController( | ||
| title: AlertMessage.courseQuestFailureLocationTitle, | ||
| message: message, | ||
| type: .normal | ||
| ) | ||
| alertController.configureMessageLabel { | ||
| $0.highlightText(targetText: "위치", font: .offroad(style: .iosTextBold)) | ||
| $0.highlightText(targetText: "내일 다시", font: .offroad(style: .iosTextBold)) | ||
| } | ||
| alertController.xButton.isHidden = true | ||
| let action = ORBAlertAction(title: buttonTitle, style: .default) { _ in | ||
| // 위치 인증 실패 시 후처리 | ||
| } | ||
| alertController.addAction(action) | ||
| self.present(alertController, animated: true) | ||
| } | ||
| } | ||
|
|
||
| } catch { | ||
| await MainActor.run { | ||
| print("탐험 인증에 실패했어요. 다시 시도해주세요.") | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P4
cell 안의 onVisit 변수에 거의 100줄 가까이 되는 클로저를 할당하고 있는 것 같은데,
이 정도의 길이면 별도 함수로 빼서 구현하는 게 좋을 것 같다는 생각이 듭니다..!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
말씀해주신 대로 onVisit 클로저의 길이가 길어 가독성과 유지보수 측면에서 부담이 될 수 있을 것 같습니다.
해당 로직은 별도 함수로 분리해 추후 리팩토링하겠습니다. 감사합니다!
...oad-iOS/Offroad-iOS/Presentation/CourseQuest/ViewControllers/CourseQuestViewController.swift
Outdated
Show resolved
Hide resolved
nolanMinsung
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수고하셨습니다!
시간이 얼마 없어서,
지금은 P1 코멘트만 먼저 반영해 주시고, 다른 코멘트는 나중에 반영해도 무방합니다.
Johyerin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
변경내용 확인했습니다아 고생하셨습니다!!
| private let typeLabelView = UIView().then { | ||
| $0.roundCorners(cornerRadius: 10) | ||
| $0.backgroundColor = .neutral(.nametagInactive) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2
지금 보니 일부 셀에 한해서 방문 버튼을 누르기 전과 후의 셀 높이 차이가 있는 경우가 확인됩니다! QA 수정 때 같이 확인해주셔야 될 것 같아용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
꼼꼼하게 확인해주셔서 감사합니다. 해당 부분은 수정하려 했으나 정확한 원인을 파악하지 못해 QA 수정 시 함께 반영할 예정입니다.
...oad-iOS/Offroad-iOS/Presentation/CourseQuest/ViewControllers/CourseQuestViewController.swift
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| clearImageView.snp.makeConstraints { | ||
| $0.trailing.equalToSuperview().inset(6) | ||
| $0.centerY.equalToSuperview() | ||
| $0.size.equalTo(75) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ScreenRecording_07-05-2025.02-03-06_1.MP4
해당 코드로는 문제 수정이 안된 것 같아서 스크린샷 같이 첨부해드리겠습니다!
...oad-iOS/Offroad-iOS/Presentation/CourseQuest/ViewControllers/CourseQuestViewController.swift
Outdated
Show resolved
Hide resolved
nolanMinsung
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수고하셨습니다!
남은 이슈들과 추가된 QA 수정사항은 새 브랜치에서 구현하는 게 좋을 것 같습니다!
Johyerin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다!!

🌴 작업한 브랜치
✅ 작업한 내용
1. 탐험 인증 버튼 동작 (onVisit) 구현
2. 탐험 성공 & 오늘 첫 방문 ((true, true))
3. 팝업 메시지 분기 처리
남은 탐험 수가 0일 경우: "퀘스트 클리어! 보상을 받아보세요" → "보상" 강조
그 외: "방문 성공! 앞으로 N곳 남았어요" → "N곳" 강조
4. 위치 인증 실패
커스텀 ORBAlertController 표시
5. 커스텀 팝업 뷰
CourseQuestPopUp사용❗️PR Point
📸 스크린샷