iOS 62

TCA사용해서 앱 만들기

오늘은 어제 익힌 TCA 개념을 바탕으로 간단한 카운터 앱을 만들어보면서 사용법을 익히고 정리해보겠습니다.아래 TCA 튜토리얼 문서를 보면서 따라서 진행했습니다!https://pointfreeco.github.io/swift-composable-architecture/main/tutorials/composablearchitecture/01-01-yourfirstfeature Documentation pointfreeco.github.io ReducerReducer는 특정 기능(Feature)에 대한 모든 비지니스 로직, 상태변화, 사이드 이펙트를 관리하는 곳입니다.//CounterFeature.swiftimport ComposableArchitecture@Reducerstruct CounterFeatur..

iOS

TCA란?

TCA(The Composable Architecture)는 앱의 상태를 일관되고 예측 가능하며 테스트하기 쉽게 관리하기 위한 Swift 라이브러리입니다. 복잡하게 얽힌 데이터 흐름을 명확한 단방향 흐름으로 정리하여, 앱이 커져도 유지보수하기 쉬운 구조를 만들어줍니다.TCA의 핵심 개념TCA는 5가지 주요 구성 요소로 이루어져 있습니다. State (상태)특정 기능을 표현하는 데 필요한 모든 데이터가 유일하게 저장되는 곳입니다. 예를 들어, 카운터 화면이라면 현재 숫자, 로딩 중인지 여부 등이 모두 State에 포함됩니다.비유: 건물의 설계도와 같습니다. 설계도만 보면 건물의 모든 구조와 상태를 알 수 있듯, State만 보면 현재 화면이 어떤 상태인지 완벽하게 파악할 수 있습니다.Action (액션)앱..

iOS

동적으로 UI 추가하기

오늘은 서버에서 받아온 데이터의 개수에 따라 버튼이나 뷰를 다르게 보여줘야 할 때, 어떻게 UI를 구성해야 할지 알아보도록 하겠습니다.UIStackView를 활용해서 동적 UI를 어떻게 구현할 수 있는지 알아보겠습니다.동적으로 버튼 생성하기아래 코드는 특정 count 값을 받아서 그 개수만큼 번호가 매겨진 버튼을 생성하고, UIStackView에 추가하는 함수입니다. 하나씩 뜯어보며 이해해 봅시다.// 버튼들을 담을 UIStackViewlet seriesButtonStackView: UIStackView = { let stackView = UIStackView() stackView.axis = .horizontal // 가로 정렬 stackView.spacing = 8.0 stack..

iOS

UIStackView의 타입과 case let 패턴

오늘은 iOS 개발에서 UIStackView 내부에 동적으로 추가된 여러개의 버튼들을 제어해야할 때 마주한 문제와 그 과정에서 사용했던 case let이라는 패턴에 대해서 공유해보려고 합니다. 당시의 문제 상황은 아래와 같습니다. UIStackView가 하나 있습니다.viewDidLoad()나 특정 시점에서 API로부터 받은 데이터 개수만큼 UIButton을 만들어 이 스택뷰에 addArrangedSubview()로 추가합니다.사용자가 여러 버튼 중 하나를 탭하면, 탭한 버튼은 활성화 상태 (파란색 배경)로 변경됩니다.동시에 나머지 모든 버튼은 비활성화 상태 (회색 배경)로 돌아가야 합니다.동적으로 생성된 버튼들을 탭할 때마다 활성 / 비활성화를 해주기 위해서 스택뷰를 for문으로 탐색하면서 버튼의 태그..

iOS

Swift Concurrency: Sendable 프로토콜

오늘은 Sendable이 무엇인지, 왜 중요한지에 대해서 알아보도록 하겠습니다.Sendable 프로토콜, 왜 필요할까요?동시성 프로그래밍의 가장 큰 문제는 바로 데이터 레이스(Data Race)입니다. 데이터 레이스는 여러 스레드가 공유된 데이터에 동시에 접근하고, 그중 하나 이상이 데이터를 수정하려고 할 때 발생합니다. 이로 인해 앱이 비정상적으로 종료되거나 예측 불가능한 결과를 초래할 수 있게됩니다.이전에는 이러한 문제를 해결하기 위해 rock이나 세마포어와 같은 메커니즘을 사용했지만, 코드가 복잡해지고 데드락의 위험이 있었습니다.Sendable 프로토콜은 바로 이 데이터 레이스 문제를 컴파일 시점에 방지하기 위해 탄생했습니다. 어떤 타입이 Sendable을 준수한다는 것은, 해당 타입의 값을 동시성..

iOS

Repository Pattern

오늘은 Repository Pattern으로 데이터 로직 분리하는 방법을 알아보겠습니다.UIKit으로 개발하다 보면 UIViewController 하나에 네트워크 통신, 데이터 파싱, UI 업데이트 등 온갖 코드가 뒤섞여 코드가 수백 줄이 넘어가는 경우가 종종 생깁니다. 이런 코드는 유지보수도 어렵고, 테스트는 더더욱 힘들어집니다.이 문제를 해결할 수 있는 방법중 하나인 리포지토리 패턴(Repository Pattern)에 대해 알아보고, 실제 코드에 적용해 보겠습니다.Repository Pattern리포지토리 패턴을 한마디로 정의하면 '데이터 소스에 대한 추상화 계층'입니다.쉽게 비유해 볼게요. 우리가 도서관에서 책을 찾는다고 생각해 봅시다. 우리는 사서에게 가서 "해리포터 책 주세요"라고 요청합니다...

iOS

코드 리팩토링하기: 의존성 역전의 원칙(DIP)

오늘은 며칠전에 작성했던 숫자야구 게임의 코드를 리팩토링한 내용을 작성해보겠습니다.지난 글에도 분명 리팩토링 내용을 작성했지만,, 의존성 역전의 원칙을 적용하는것에 대한 피드백을 받아서 DIP를 적용하여 리팩토링해보았습니다! 먼저 의존성 역전의 원칙이란?Dependency Inversion Principle(DIP)SOLID 원칙중의 하나로 세부적인 구현이 아닌 추상화에 의존해야한다는 원칙입니다. 보통 코드를 작성하면 상위 모듈(전체 흐름 제어기)이 하위모듈(세부 구현 내용)을 직접 가져다가 쓰는 의존관계가 생기게됩니다.예시를 들어 설명하자면 야구게임에서 게임 전체 흐름을 제어하는 부분이 랜덤 숫자를 생성하는 세부 구현 내용을 직접 호출하여 구현을 하게됩니다. 이 구조에서는 야구게임이 랜덤숫자생성기라는..

iOS

메소드 디스패치

메소드 디스패치란 메소드를 호출했을 때 어떤 코드가 실행되어야하는지를 결정하고 연결해주는 메커니즘입니다.메소드 디스패치는 정적 디스패치(Static Dispatch)와 동적 디스패치(Dynamic Dispatch) 두 가지 방식으로 나뉩니다.정적 디스패치 (Static Dispatch)정적 디스패치는 컴파일 시점에 어떤 메소드를 호출할지 미리 결정하는 방식입니다. 컴파일러가 코드의 타입 정보를 바탕으로 실행할 함수의 메모리 주소를 파악하고, 해당 주소를 호출 코드에 직접 삽입합니다. 이를 '직접 호출(Direct Call)'이라고도 부릅니다.특징은 컴파일 타임에 호출 정보를 결정하기 때문에 런타임에 속도가 빠릅니다.동적 디스패치 (Dynamic Dispatch)동적 디스패치는 런타임 시점에 어떤 메소드를..

iOS

야구게임 프로젝트 리팩토링 과정

오늘은 최근에 만들어본 Swift 콘솔 야구 게임 프로젝트의 리팩토링 과정을 공유하려고 합니다.처음에 모든 로직이 하나의 클래스에 뭉쳐 있어서 코드가 길어지고, 하나의 클래스에서 많은 책임을 가지고 있었습니다. 그래서 단일 책임 원칙을 적용하며 코드를 훨씬 더 깔끔하고 유연하게 수정해보았습니다.BaseballGame 클래스에서 담당하던 일처음 작성했던 BaseballGame 클래스에는 야구 게임에 필요한 모든 로직이 들어있었습니다.createNumber(): 3자리 정답 숫자를 생성createUserGuess(): 사용자 입력을 받음if-else 문: 입력값이 유효한지(숫자인지, 3자리가 맞는지, 중복은 없는지 등) 검사judgeNumber(): 스트라이크와 볼을 판정이 모든 책임이 한 클래스에 모여 있..

iOS

Swift Concurrency(Actor, @MainActor)

오늘은 동시성 프로그래밍의 문제중 하나인 데이터 레이스에 대해 알아보고 해결하기위한 방법을 공부해보겠습니다.Data Race데이터레이스란 두개 이상의 스레드가 동시에 하나의 메모리에 접근하여 쓰기(수정) 작업을 할 때 발생하는 문제입니다.동시에 같은 메모리에 접근하여 데이터를 수정하게 된다면 어떤 결과가 나오게될 지 예측이 어렵기 때문에 문제가 생기게 됩니다.한가지 예시를 들어보겠습니다. 하나의 계좌에 10,000원이 들어있습니다. 이 계좌에 스레드 A와 B가 동시에 접근하는 상황을 설명해보겠습니다.1. 스레드 A가 잔액을 읽습니다 (잔액: 10,000원)2. 스레드 B도 잔액을 읽습니다 (잔액: 10,000원)3. 스레드 A에서 10,000원을 입금합니다 (잔액: 20,000원)4. 스레드 B에서 2,..

iOS