Skip to content

Comments

[Feat] 행담이 이름 수정 기능#173

Open
emilyj4482 wants to merge 12 commits intodevfrom
feature/rename-hangdam
Open

[Feat] 행담이 이름 수정 기능#173
emilyj4482 wants to merge 12 commits intodevfrom
feature/rename-hangdam

Conversation

@emilyj4482
Copy link
Collaborator

@emilyj4482 emilyj4482 commented Feb 26, 2025

1. 요약

현재 키우는 행담이만 이름 변경할 수 있게 구현

2. 스크린샷

Screen Recording 2025-02-26 at 10 44 14

3. 공유사항

  1. textfield + rightview(담이 고정 label)를 넣은 alert을 SwiftUI 컴포넌트로는 만들 수 없어, UIKit으로 만들고 UIViewControllerRepresentable을 통해 SwiftUI에서 사용할 수 있게 했습니다.
  2. 이 과정에서 AlertManager 리팩토링도 동반했습니다.
  • 설정으로 이동 버튼을 가진 알럿을 작성 뷰와 설정 뷰에서 공동 사용하도록 메소드 통일
  • 알럿 title과 message가 하드코딩 되어있던 부분을 AlertCase로 추가
  • AlertMessage enum을 AlertCase로 리네이밍 : 알럿을 띄우는 case에 따라 titlemessage를 계산 프로퍼티로 갖고 있기 때문에, (AlertMessage.title, AlertMessage.message 보다는 AlertCase.title, AlertCase.message가 더 적절하다고 판단) 상위 개념인 case 단어를 사용하는 것으로 수정했습니다.
  1. 행담이 상태 뷰(HangdamStatusView)에서 행담이 데이터에 대한 Update가 추가되는 만큼 ViewModel이 필요해짐
  • 뷰 바인딩 레이어였던 ContentViewModel에 넣어서 주입하는 방식으로 코드 변경
  • 어떤 행담이를 수정하는지 알아야하기 때문에 StatusContent가 행담이 id를 갖고 있어야 함 (StatusContent에 id 프로퍼티 추가)
  1. 행담이 이름 변경 동작은 HangdamStatusView(자식 뷰)에서 이뤄지는데, HappinessListView(부모 뷰)의 뷰도 리로드가 되어야 해서 (행담이가 먹은 기억들 title 리로드) 변경 시점에 Notification post를 통해 HappinessListView가 viewModel.reloadData()를 호출하도록 구현했습니다.
.onReceive(NotificationCenter.default.publisher(for: Notification.hangdamRenamed)) { _ in
    viewModel.reloadData()
}
  1. 자잘한 오타 수정, 불필요한 코드 삭제, 네이밍 리팩토링 등 코드 정리 많습니다.

@emilyj4482 emilyj4482 added the enhancement New feature or request label Feb 26, 2025
@emilyj4482 emilyj4482 self-assigned this Feb 26, 2025
@emilyj4482 emilyj4482 linked an issue Feb 26, 2025 that may be closed by this pull request
4 tasks
Comment on lines 46 to 53
/// 이름 입력 알럿 표시
/// - Parameter completion: 사용자가 입력한 이름을 반환하는 클로저
func showNameInputAlert(completion: @escaping (String?) -> Void) {
let alertController = UIAlertController(
title: "이름 지어주기",
message: "한 번 정한 이름은 바꿀 수 없으니 \n 신중하게 지어주세요!",
title: AlertCase.nameHangdam.title,
message: AlertCase.nameHangdam.message,
preferredStyle: .alert
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

AlertCase로 정리한걸 사용하니 코드가 엄청 깔끔해졌네요 정말 , 고생하셨습니다!!

init(viewModel: HappinessListViewModel, isBackButtonHidden: Bool) {
self.viewModel = viewModel
self.isBackButtonHidden = isBackButtonHidden
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

init 구문을 지우고 HappinessListView가 생성될 때 바로 viewModel에 넣어주도록 바꾸신 이유가 뭔지 궁금합니당

Copy link
Collaborator Author

@emilyj4482 emilyj4482 Feb 28, 2025

Choose a reason for hiding this comment

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

사실 결과적으로는 init이 있든없든, HappinessListView가 생성될 때 viewModel을 주입해주는 것은 같습니다. (init이 생성자니까요) HappinessListView가 struct라서 멤버와이즈 이니셜라이저가 제공되기 때문에, 개인적인 선호로 init 코드를 생략하는 편입니다. viewModel이외에 다른 값(예를 들어 isBackButtonHidden)이 있다면 명시적으로 정의하는 게 리스트 뷰에 필요한 값들이 뭔지 알 수 있어 정의했겠지만, 더이상 isBackButtonHidden은 사용하지 않는 값이어서 삭제해야했고 그렇게 되면 viewModel만 갖고 있기 때문에 생략하는 것이 더 깔끔하다고 느꼈습니다. 실제로 SwiftUI에서 ObservedObject로 viewModel을 갖고 있는 경우 이니셜라이저를 생략한 코드를 많이 보기도 했습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

아하 멤버와이즈 이니셜라이저..!! 그렇네요 SwiftUI 코드 볼 때 Class가 아니라 Struct인게 눈에 띄긴 했었는데, Struct이어서 생성자를 명시하지 않아도 되겠군요. SwiftUI의 특징인건가 했는데 그보다는 Struct이라 그렇다고 봐야겠네용


protocol HangdamRenaming {
func renameHangdam(id: String, newName: String)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

HangdamRenaming 프로토콜이 다른데선 쓰이지 않는 거 같은데 역할이 뭔지 알 수 있을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

진홍님이 의존성 주입 리팩토링 작업하실 때 (mapper, factory, operator 등 만드신 작업) 작성하신 다른 operator 코드의 컨벤션을 맞춘 것입니다. DetailViewOperator 코드를 보니 메소드 역할마다 프로토콜을 정의하셨더라고요 (결론 : 저도 잘 모르겠습니다)

Copy link
Collaborator

@maxminseok maxminseok Feb 28, 2025

Choose a reason for hiding this comment

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

진홍님이 하신 건 아마 의존성 주입 때문이었지 않을까 싶습니당..
HangdamStatusViewModel에서 private let statusViewOperator: StatusViewOperator 이 부분의 타입을 StatusViewOperator가 아니라 HangdamRenaming으로 하면, 의존성 주입 해줄 때 HangdamRenaming 프로토콜을 따르는 다른 객체로 갈아끼울 수 있어서 좀 더 유연하니까요.
근데 다른 객체로 갈아끼울 일 없다고 하면 굳이 필요 없지 않나 싶기도한데 다른 분들은 어떻게 생각하는지 궁금하네요..🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

맞아요 프로토콜의 쓰임새가 그런 것 같더라고요. 아직까지 구현체를 갈아끼우는 걸 경험해보지 못해서 저 코드의 필요성이 실감나지 않는 단계인데.. 그렇게 많이 들었습니다. 지금 단계에서 저희 프로젝트에서 꼭 필요한 건 아닌 거 같네요 먼훗날의 가능성을 생각해서 넣으셨다고 생각중입니다 ㅋㅋㅋ

import UIKit

/// SwiftUI View에서 UIAlertController를 사용하기 위한 객체
struct AlertControllerWrapper: UIViewControllerRepresentable {
Copy link
Collaborator

Choose a reason for hiding this comment

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

SwiftUI와 UIKit을 연결해주는 프로토콜인가보네요..! 기억해둘 필요가 있겠네요. 최종 발표회때 튜터님이 UIKit과 SwiftUI 데이터 전달 물어 보셨는데 이런 부분에 대해 여쭤봤던 건가 싶네요.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

저는 그 질문을 들었을 때 화면 간의 이동 시 데이터 전달로 느껴지긴 했었어요 (예를 들어 리스트 뷰에서 디테일 뷰로 이동할 때, 어떤 행복을 탭했는지 행복 id 전달) 그런데 저희는 swiftui와 uikit 화면 간의 이동은 없다보니 (탭이 분리되어있어서) 해당사항이 없다고 생각했습니다. 저 프로토콜은 저도 이번에 alert을 하면서 처음 써봤는데 앞으로 유용할 거 같더라고요!

init(viewModel: HappinessListViewModel, isBackButtonHidden: Bool) {
self.viewModel = viewModel
self.isBackButtonHidden = isBackButtonHidden
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

아하 멤버와이즈 이니셜라이저..!! 그렇네요 SwiftUI 코드 볼 때 Class가 아니라 Struct인게 눈에 띄긴 했었는데, Struct이어서 생성자를 명시하지 않아도 되겠군요. SwiftUI의 특징인건가 했는데 그보다는 Struct이라 그렇다고 봐야겠네용


protocol HangdamRenaming {
func renameHangdam(id: String, newName: String)
}
Copy link
Collaborator

@maxminseok maxminseok Feb 28, 2025

Choose a reason for hiding this comment

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

진홍님이 하신 건 아마 의존성 주입 때문이었지 않을까 싶습니당..
HangdamStatusViewModel에서 private let statusViewOperator: StatusViewOperator 이 부분의 타입을 StatusViewOperator가 아니라 HangdamRenaming으로 하면, 의존성 주입 해줄 때 HangdamRenaming 프로토콜을 따르는 다른 객체로 갈아끼울 수 있어서 좀 더 유연하니까요.
근데 다른 객체로 갈아끼울 일 없다고 하면 굳이 필요 없지 않나 싶기도한데 다른 분들은 어떻게 생각하는지 궁금하네요..🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 행담이 이름, 행복 기록 수정 기능

3 participants