Skip to content
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

Feat/#172 검색로직 수정 #177

Open
wants to merge 14 commits into
base: juri
Choose a base branch
from
Open

Conversation

hooni0918
Copy link
Collaborator

🔗 연결된 이슈

📄 작업 내용

  • 검색시 해당 지역 포커싱
  • 검색시 해당지역 맛집들만 리스트업
구현 내용 IPhone 15 pro IPhone SE
GIF

💻 주요 코드 설명

  • �검색 화면에서 특정 위치 상세 화면으로 이동할 때, 검색 화면은 스택에서 제거하고 위치 상세 화면을 새로 추가하는 로직
  • 검색 pop 하자마자 push하는 로직입니다. 이게 없으면 mapPath에서 경로를 못찾아서 fatalError가 납니다
func navigateToSearchLocation(locationId: Int, locationTitle: String) {
        if let lastView = mapPath.last,
           case .searchView = lastView {
            pop(1)
        }

        push(.searchLocationView(
            locationId: locationId,
            locationTitle: locationTitle
        ))
    }

HomeViewModel

  • 주석으로 로직 대체

👀 기타 더 이야기해볼 점

API 추가 + 기존 한 파일에 있던 코드들을 각 구조체별로 분리 + 동일한 UI를 가진 바텀시트 추가 가 되어 코드 뻥튀기가 심함니다. 천천히 슥슥 넘기면서 보셔도 무방합니다.
슥슥 넘기고 네비게이션매니저 파일부터 보셔도 됩니다

Actor클래스는 불필요해서 일부로 다시 전부 제외햇습니다. 추후 리팩토링때 반영할게요!

@hooni0918 hooni0918 added feat 기능구현시 사용 Jihoon 나는지훈 labels Jan 31, 2025
@hooni0918 hooni0918 self-assigned this Jan 31, 2025
do {
let responseDto = try response.map(BaseResponse<ResturantpickListResponse>.self)
guard let data = responseDto.data else {
throw NSError(domain: "HomeService", code: -1, userInfo: [NSLocalizedDescriptionKey: "No data available"])
Copy link
Member

@thingineeer thingineeer Feb 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 무슨 에러 인가요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetchLocation 에 대한 기본 에러타입 지정을 안해서 기본 NSError로 전부 빼놓았습니다 (fatalerror같은종류,,)
해당 코드 에러케이스 추가해서 넣어두겟습니다

defaultPlaceholder
case .empty:
defaultPlaceholder
@unknown default:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 그렇고, 다른 곳도 그렇고 AsyncImage@unknown 키워드를 꼭 붙여 줘야하나요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저번에 말햇듯 당시 린트에러인줄 모르고 붙여놧던것들입니다

Color.clear.frame(height: 90.adjusted)
}
}
.coordinateSpace(name: "scrollView")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 봤을때는, coordinateSpace 활용하는 곳이 없는 것 처럼 보이는데, 어디에서 활용하나요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

원래는 Geometry 를 사용할떄 같이 부모뷰(여기서는 스크롤뷰) 의 위치를 보고 움직여야할때 사용이 되는데요 기존 코드상 바텀시트 중간너비에서 스크롤이 될때 사용햇던 코드인데 해당 부분이 빠지면서 남아있는 코드입니다 삭제해둘게요

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앱잼때는 안 물어봤는데, 파일 ViewModel로 네이밍을 하신 건 실수인가요? 아니면 의도인가요

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어떤의도의 질문인지 모르겟어요

  1. 왜 뷰모델을 사용해서 MVVM을 사용한 것인가
  2. ViewModel 이라는 말이 이상한것인가
    1번이라면 이전 PR 설명에서 홈에서의 VIew-Only 로직이 너무 복잡해서 일단 간단하게나마 뷰모델에 분리를 햇다 하지만 MVVM은 아니다 라고 말씀드렷고 2번인 경우에 어떤이름으로 바꾸는게 좋을까요?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

왜 여기만 ViewModel이 있는 것인가에 대한 질문이었는데, 로직이 너무 복잡해서 분리를 하셨군요

원래 아키텍처라면 저희는 MVI를 따라야 하는데 여기는 MVI가 아니어서 여쭤본 겁니다!

Comment on lines +53 to +77
func fetchLocationList(locationId: Int) async {
isLoading = true
do {
clearFocusedPlaces()
selectedLocation = nil

// API 호출하여 새 데이터 받아오기
let response = try await service.fetchLocationList(
userId: Config.userId,
locationId: locationId
)

// 데이터가 성공적으로 받아와진 후에만 기존 리스트 교체
self.pickList = response.zzimCardResponses

// 첫 번째 장소가 있다면 지도 중심점 이동
if let firstPlace = response.zzimCardResponses.first {
self.selectedLocation = (firstPlace.latitude, firstPlace.longitude)
}
} catch {
self.error = error
print("Error in fetchLocationList:", error)
// 에러 발생 시 기존 데이터 유지
}
isLoading = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기 함수 블럭에는 Task { ... } 가 왜 없나요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

async 를 사용한 함수이기에 사용할 필요가 없습니다.
Task 를 사용할때에는 비동기 컨텍스트가 아닐때 해당 컨텍스트를 비동기로 받겟다 라는 의미이기에 해당 코드에서는 필요가 없습니다.
단, 이렇게 async 로 지정한다면 하위 컨텍스트가 모두 비동기로 지정되지만 해당 뷰모델 자체가 비동기로 돌아가야해서 큰 상관은 없을것같아 사용햇습니다

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

예를 들어 성수동, 성수 등 을 입력했는데, 서버 호출에 빈값이 와서, 이 부분 서버분들에게 건의해야 할 것 같습니다.!
(서버 호출에 대한 문제는 아님)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당부분은 서버 구현이 안된게 맞습니다 현재 서버에서 불러올수있는값은 마포 강남 의 경우에만 가능할거에요

Copy link
Collaborator

@ChoiAnYong ChoiAnYong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

Comment on lines +25 to +32
return lhs.placeId == rhs.placeId &&
lhs.placeName == rhs.placeName &&
lhs.placeAddress == rhs.placeAddress &&
lhs.postTitle == rhs.postTitle &&
lhs.photoUrl == rhs.photoUrl &&
lhs.latitude == rhs.latitude &&
lhs.longitude == rhs.longitude &&
lhs.categoryColorResponse == rhs.categoryColorResponse
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

placeId가 고유한 값이 아닌가요?
고유한 값이라면 나머지 값들도 비교하는 이유가 있을까요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금은 수정이 되었는데 해당 코드 작성시에 해당 placeID 와 식당 정보들이 매핑이 이상하게 내려오고 있었습니다.
현재는 수정되어있으니 placeID가 유일한 코드가 맞아요!

Comment on lines 31 to 34
.frame(width: 16, height: 16)
default:
Color.clear
.frame(width: 16, height: 16)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adjusted 넣어주세요!

Comment on lines 61 to 62
.padding(.vertical, 12)
.padding(.horizontal, 12)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.padding(12)로 해도 될 것 같습니다!

Comment on lines 30 to 33
.frame(width: 16, height: 16)
default:
Color.clear
.frame(width: 16, height: 16)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adjusted 넣어주세요!

Comment on lines 62 to 63
.padding(.vertical, 12)
.padding(.horizontal, 12)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 padding(12)로 해도 될 것 같습니다!

@@ -16,7 +16,7 @@ final class NavigationManager: ObservableObject {

@Published var popup: PopupType?

@ViewBuilder
@MainActor @ViewBuilder
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mainactor를 추가하신 이유가 뭔가요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

원래는 해당 builder 에서 뷰 전환 로직을 해당 builder에서 모두 가진채로 화면 전환이 필요해서 권한을 넣었을때 줫던 코드입니다.
해당 코드에서는 필요없는게 맞습니다. 지우도록할게요

@@ -9,7 +9,7 @@ import Foundation

@MainActor
final class HomeViewModel: ObservableObject {
private let service: HomeServiceType
let service: HomeServiceType
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

외부에서 사용하는 곳이 없는 것 같은데 private를 쓰지 않은 이유가 있나요?

Copy link
Collaborator

@juri123123 juri123123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

.background(.white)
.cornerRadius(10, corners: [.topLeft, .topRight])
.offset(y: UIScreen.main.bounds.height - currentStyle.height + offset)
.gesture(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simultaneousGesture랑 그냥 gesture의 차이가 있나요?

Comment on lines +83 to +88
case .failure:
defaultPlaceholder
case .empty:
defaultPlaceholder
default:
defaultPlaceholder
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

하나로 묶어도 좋을 것 같아요 ! 개인취향..

@@ -72,4 +74,16 @@ final class NavigationManager: ObservableObject {
}
}

func navigateToSearchLocation(locationId: Int, locationTitle: String) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

변수 currentLocation이랑 locationTitle이 다른 역할을 하나요 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat 기능구현시 사용 Jihoon 나는지훈
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feat] 검색후 포커싱
4 participants