Aggregate Model (1)
Aggregate Model: Bounded Context를 활용한 대규모 앱 설계 단순히 화면마다 뷰모델을 만드는 방식에서 벗어나, 앱의 규모에 따라 데이터 원천을 어떻게 논리적으로 격리하고 관리할 것인지에 대한 아키텍처적 가이드라인을 정리한다. 1. 단일 모델 구조 (Small to Medium Apps) 앱이 작거나 중간 규모일 때는 하나의 ...
Aggregate Model: Bounded Context를 활용한 대규모 앱 설계 단순히 화면마다 뷰모델을 만드는 방식에서 벗어나, 앱의 규모에 따라 데이터 원천을 어떻게 논리적으로 격리하고 관리할 것인지에 대한 아키텍처적 가이드라인을 정리한다. 1. 단일 모델 구조 (Small to Medium Apps) 앱이 작거나 중간 규모일 때는 하나의 ...
커피 주문 앱의 기존 MVVM 코드 분석 강의에서 제공된 프로젝트(커피주문앱)는 기능을 수행하는 데 문제가 없으나, 레이어 간의 강한 결합과 반복적인 의존성 주입이 구조적 복잡성을 야기함. 리팩토링 전의 핵심 로직들을 정리함. 1. ViewModel의 구조적 복잡성 각 View는 고유한 ViewModel을 가지며, 모든 통신 로직이 이 계층에 갇혀...
MVVM의 기원: Presentation Model (by Martin Fowler) 많은 개발자가 MVVM을 마이크로소프트가 WPF를 위해 만든 최신 패턴으로 알고 있지만, 그 뿌리는 2004년 마틴 파울러가 제안한 ‘Presentation Model’에 있다. 이 개념을 이해하면 SwiftUI가 왜 지금의 형태가 되었는지 더 명확해진다. 1. ...
SelectBooksView에서 VM 연결하기 실제 결제 기능을 연결하기에 앞서, 기존에 임시로 사용했던 시뮬레이션용 로직들을 정리한다. LockedBookView(book: book) .onTapGesture { showTempAlert.toggle() // 제거 game.bookQuestio...
In-App 결제 기능 구현 개발자 멤버십을 새롭게 연장한 기념으로, 중단되었던 강의 내용을 다시 정리한다. 인앱 결제(IAP) 기능을 구현하기 위해서는 Apple 개발자 멤버십 가입이 필수적이다. 결제 기능을 구현할 때 핵심이 되는 프레임워크는 StoreKit이다. StoreKit Docs 참고 StoreKit 한글 설명 참고 1. ...
강의에 있던 내용을 정리한다. 📱 6 Key Phases of iOS App Development 💡 Phase 1 - Ideation 앱 아이디어 선정: 본인의 페인 포인트(Pain Points)에서 아이디어를 찾는다. 즉시 기록: 아이디어가 떠오르는 즉시 기록하여 보존한다. 🧠 Phase 2 - Brainstorm 기능 정의:...
Next Level 버튼 애니메이션 추가 시작하기 앞서 Next Level 버튼에 phaeAnimator를 사용하여 약간의 생동감을 부여해주었다. .phaseAnimator([false, true]) { content, phase in content .scaleEffect(phase ? 1.2 : 1) } 이렇게 버튼이...
이번글은 좀 중간에 끊기가 애매해서 내용이 좀 길어질 것 같다. GamePlayView 위의 사진과 같이 디자인을 해보도록 한다. 지난글에서 틀을 짠걸 기반으로 진행한다. Controls @Environment(Game.self) private var game @Environment(\.dismiss) private var dismiss ...
GamePlayView 이전글에서 게임로직을 구현해놓았으니, 이제는 직점 게임을 하는 것에 대한 UI를 그려본다. 그전에 PlayButton에 있는 @State private var playGame = false 이걸 ContentView로 옮겨준다. 왜냐면 Playbutton에서는 @Binding Wrapper를 사용할 예정이기 때문 그렇...
Game Logic 가장 중요한 게임로직을 만들어 본다. 우선 로직에 필요한 변수들을 먼저 만들어준다. var gameScore = 0 var questionScore = 5 var recentScores = [0, 0, 0] var activeQuestions: [Question] = [] var answeredQuestions: [Int] ...