
cursor AI 를 사용하여 SwiftUI 로 신규 화면들, 기능들을 구현하고 있는 과정에서
아키텍처 상으로 공통적으로 계속 수정요청을 했던 부분들이 있었다.
View 에서 ViewModel 로 옮길 수 있을까?
여러 ViewModel 에서 사용될 것 같아서 UseCase로 옮길 수 있을까?
여러 View 에서 사용될 것 같아서 modifier 처럼 공통으로 사용할 수 있는 부분으로 수정해줄 수 있을까?
cursorAI 가 기본적으로 원하는 기능 혹은 오류 상황 등을 명확히 설명하면 context 상으로 다 추가하지 않더라고 정확히 이해하고 해결책을 제시하고는 합니다.
그리고 이 과정에서 추가로 생성이 필요한 파일도 생성해주기도 합니다.
다만 위 세 가지 처럼 View, ViewModel, UseCase, Modifier 등으로 분리시키는 관점에서는 약한 것 같아서
저만의 공통 아키텍처가 좀 잡힌 것 같아 이참에 프롬프트 가이드라인을 생성해봤습니다.
이 가이드라인은 SwiftUI 애플리케이션의 아키텍처를 일관성 있고 확장 가능하게 유지하는 것을 목표로 합니다.
View는 UI 렌더링과 사용자 입력 처리에 집중합니다.
@State)를 제외한 모든 상태는 ViewModel의 @Published 프로퍼티를 통해 전달받아 사용합니다.viewModel.send(Action) 함수를 통해서만 전달합니다.Modifier로 분리하여 재사용성을 높입니다.Alert나 Sheet는 ViewModel의 @Published 상태 변수(예: showAlert, showShareSheet)에 바인딩하여 표시합니다. View는 알림의 내용이나 표시 여부를 직접 결정하지 않습니다.ViewModel은 View를 위한 상태를 관리하고, View로부터 받은 액션을 처리합니다.
send(Action:) 메서드 하나로 통일하고, 그 외의 모든 내부 처리 함수는 private으로 선언하여 외부 노출을 최소화합니다.do-catch 구문을 통해 처리합니다. 오류 발생 시, 사용자에게 피드백을 주기 위한 alertContent를 설정하고 showAlert를 true로 변경합니다.@Published 프로퍼티를 통해 전달합니다.UseCase는 특정 비즈니스 로직을 수행하는 단일 책임을 가집니다.
protocol을 정의하고, 실제 구현체는 Default...UseCase로 작성합니다. UseCase 내에서 발생할 수 있는 오류는 별도의 Error 열거형으로 상세하게 정의합니다.execute 함수를 통해 이루어지며, 필요한 input을 받아 처리 후 output을 반환합니다.throws를 사용하여 오류가 발생했음을 명확하게 알리고, ViewModel 단에서 catch하여 처리하도록 구현합니다.모든 사용자 대상 문자열은 현지화를 고려하여 관리합니다.
TLRKey, TLRko, TLRen, TLRzh 파일에서 중앙 관리합니다.TLRKey 파일 내 열거형(enum)에 case로 추가합니다. 키 이름은 {대분류}_{요소}_{상세설명} 규칙을 따릅니다. (예: Common_Popup_SaveFailed)TLRko에 기준이 되는 한국어 문장을 추가하고, 이를 바탕으로 TLRen(영어), TLRzh(중국어 간체)에 번역된 값을 추가합니다.Localized.string(.yourKey) 형태로 키를 사용하여 현지화된 문자열을 가져옵니다.This guideline aims to maintain a consistent and scalable architecture for the SwiftUI application.
The View's primary responsibility is to render the UI and handle user input.
@State), all state should be received from the ViewModel's @Published properties.viewModel.send(Action) function to forward data or request logic execution from the ViewModel.Modifiers.Alerts and Sheets by binding to @Published state variables from the ViewModel (e.g., showAlert, showShareSheet). The View should not decide the content or the visibility of these presentations itself.The ViewModel manages the state for the View and processes actions received from it.
send(Action:) method. All other internal processing functions should be declared private to minimize exposure.do-catch statement. Upon catching an error, set the alertContent and change showAlert to true to provide feedback to the user.@Published properties.A UseCase has a single responsibility to perform a specific piece of business logic.
protocol for a clear interface and name the concrete implementation Default...UseCase. Define potential errors within a dedicated Error enum for clarity.execute function that takes an input and returns an output.throws to signal an error over returning an Optional. This ensures errors are explicitly handled via catch in the ViewModel.All user-facing strings must be managed with localization in mind.
TLRKey, TLRko, TLRen, and TLRzh files.cases within the enum in the TLRKey file. Key names must follow the {Scope}_{Component}_{Description} convention (e.g., Common_Popup_SaveFailed).TLRko, then add its English and Simplified Chinese translations to TLRen and TLRzh respectively.Localized.string(.yourKey) to retrieve the localized string.위 영문 내용을 토대로 mdc 가이드라인은 추가해봤습니다

그러면 이렇게 chat 상에서 context 로 추가하면 가이드라인 지침을 추가할 수 있습니다

아래는 가이드라인 생성을 위해 요청했던 프롬프트 문장입니다.
이제 만족스럽구만
근데 앞으로 계속 이렇게 리펙토링에 대해 내가 요구하는 상황들이 점점 많아질 것 같은데 공통적인 패턴이 눈에 보이거든
이를 cursor ai 인 너한테 요청하는 프롬프트상의 "지침"으로 추가하고자 하는데 정리해줄 수 있을까?
내가 느낀 부분들은 다음과 같아.
# SwiftUI View
- [관심사 분리] 모든 처리를 View 에서 하려고 하면 안된다. 관심사 분리 관점에서 View에 해당하는지 고려해야 한다.
- [관심사 분리] ViewModel 의 @Published 프로퍼티로 관리 가능한지 고려해야 한다.
- [관심사 분리] ViewModel 로 요청이 필요한 경우 항상 viewModel.send 함수를 통해 요청해야 한다.
- [Modifier] View 에서 처리해야 하지만 여러 View 에서 사용될 수 있는 기능이라면 Modifier 로 뺄 수 있는지 고려해야 한다.
- [Alert] Alert 가 필요한 경우는 viewModel 의 showAlert, alertContent 를 토대로 alert를 구현한다.
# ViewModel
- [관심사 분리] View 로부터 요청은 항상 send 함수를 통해 요청받아야 한다. 그 외는 private 함수로 관리한다.
- [관심사 분리] ViewModel 에서 처리해야 하지만 여러 ViewModel 에서 사용될 수 있는 기능이라면 UseCase 로 뺄 수 있는지 고려해야 한다.
- [오류 핸들링] UseCase로부터, 혹은 ViewModel 내에서 catch 문을 사용하여 오류를 받게 되면 alert를 표시하도록 구현한다.
- [Alert] Alert 가 필요한 경우는 showAlert, alertContent 프로퍼티를 통해 View로 전달한다.
# UseCase
- [관심사 분리] UseCase 는 프로토콜과 Error 를 지녀 execute 함수를 통해 input -> output 역할을 담당한다.
- [오류 핸들링] throws 를 사용하여 오류가 발생되면 ViewModel 단에서 catch 되도록 구현한다.
# Localized
- [파일들] 로컬라이징 문구들은 TLRKey, TLRko, TLRen, TLRzh 로 관리한다.
- [사용] 로컬라이징 문구 사용은 Localized.string(key값) 형식으로 사용한다.
- [key] key 값 추가는 TLRKey 파일 내 case 문을 추가한다. key 값 명칭 구조는 {큰범위}_{요소}_{설명} 에 따른다.
- [value] value 값 추가는 한국어 문장을 기준으로 영문장, 중국어 간체 문장으로 번역하여 각각 TLRko, TLRen,TLRzh 에 반영한다.
-> 가이드라인 생성
