본문 바로가기

전체 글173

[Swift] IUO (Implicitly Unwrapped Optional, 옵셔널 묵시적 추출) !를 타입 뒤에 붙여 선언하는 특수한 Optional이다. 일반 Optional(?)처럼 nil을 가질 수 있지만, 사용할 때 자동으로 언래핑된다.let a: String? = "hello" // 일반 Optional → 사용 시 언래핑 필요let b: String! = "hello" // IUO → 사용 시 자동 언래핑 Optional과 비교let a: String? = "hello"print(a) // Optional("hello")print(a!) // "hello" — 강제 언래핑 필요let b: String! = "hello"print(b) // "hello" — 자동 언래핑 nil일 때 동작의 차이let a: String? = nilpri.. 2026. 3. 15.
[Swift] borrowing, consuming Swift 5.9(SE-0377)에서 소유권 제어(Ownership Control) 키워드가 공식 도입되었다.borrowing, consuming, copy를 이해하면 값 타입의 메모리 흐름을 훨씬 정밀하게 제어할 수 있다. 왜 필요한가?Swift에서 값 타입(struct, enum)을 함수에 전달하면 기본적으로 복사(copy)가 발생한다.struct Packet { var payload: [UInt8] = Array(repeating: 0, count: 65536) // 64KB}func validate(_ packet: Packet) -> Bool { return packet.payload.first == 0xFF // 읽기만 하는데도 64KB를 통째로 복사}단순히 읽기만 하는데 매번.. 2026. 3. 15.
[Combine] Future, Deferred Future단 하나의 값 또는 에러를 비동기적으로 방출하는 Publisher주로 콜백 기반 비동기 API를 Combine 스트림으로 래핑할 때 사용한다.개념Future → 값 1개 방출 후 즉시 완료 또는 에러 방출 후 즉시 종료 Publisher 방출 횟수Just1번 (동기)Future1번 (비동기)PassthroughSubjectN번[1,2,3].publisherN번 시그니처final class Future: Publisher { init(_ attemptToFulfill: @escaping (@escaping Promise) -> Void)}// Promise의 정의typealias Promise = (Result) -> VoidPromise는 단순히 Result를 받는 클로저 .. 2026. 3. 12.
[Combine] .handleEvents handleEvents는 Publisher의 생명주기 이벤트를 side effect로 처리하는 오퍼레이터스트림 자체는 변형하지 않고, 각 이벤트 시점에 끼어들어 부가 작업을 수행개념map, filter 같은 오퍼레이터는 값을 변환하지만, handleEvents는 값을 그대로 통과시키면서 관찰 및 부가 작업만 수행upstream ──→ handleEvents (관찰만, 변형 없음) ──→ downstream ↓ side effect 실행 (로깅, 로딩 상태 변경 등)시그니처모든 파라미터가 optional이라 필요한 것만 골라서 사용할 수 있음func handleEvents( receiveSubscription: ((Sub.. 2026. 3. 12.
[Combine] .removeDuplicates() removeDuplicates는 연속으로 중복되는 값을 필터링하는 오퍼레이터동작 원리upstream에서 값이 방출될 때마다 바로 이전 값과 비교해서, 같으면 무시하고 다르면 downstream으로 전달[1, 1, 2, 2, 2, 3, 1, 1] ↓ removeDuplicates[1, 2, 3, 1 ]전체 중복이 아니라 연속 중복만 제거위처럼 1이 다시 나와도 앞의 3과 다르면 통과기본 사용법Element가 Equatable을 준수하면 아무 인자 없이 사용 가능let values = [1, 1, 2, 2, 3, 3, 1].publishervalues .removeDuplicates() .sink { print($0) }// 출력: 1, 2, 3, 1커스텀 비교 조건Eq.. 2026. 3. 11.
[Swift] KeyPath Swift를 쓰다 보면 \.name, \User.age 같은 문법을 마주치게 된다.Combine의 assign(to:on:), SwiftUI의 Binding, sorted(by:) 같은 곳에서 자주 등장한다.이 글에서는 KeyPath가 무엇인지, 왜 필요한지, 실제로 어디서 어떻게 쓰이는지를 정리한다. KeyPath란?KeyPath는 "어떤 타입의 어떤 프로퍼티로 가는 경로"를 값으로 표현한 것이다.일반적인 프로퍼티 접근은 특정 인스턴스에 묶여 있다.struct User { var name: String var age: Int}let user = User(name: "보경", age: 25)print(user.name) // "보경" — user라는 특정 인스턴스의 name에 접근 반면 Ke.. 2026. 3. 8.
[SwiftUI] @State, @Binding, Projected Value SwiftUI에서 뷰 간에 데이터를 주고받을 때 @State, @Binding, 그리고 $ 기호를 사용한다.각각이 무엇인지, 왜 필요한지, 내부적으로 어떻게 연결되는지를 순서대로 정리한다. 1. Source of Truth — 데이터는 한 곳에서만 소유한다SwiftUI의 데이터 흐름은 Source of Truth 원칙 위에서 동작한다.Source of Truth란 "어떤 상태가 딱 한 곳에서만 관리되고, 나머지는 그걸 참조한다"는 원칙이다.Source of Truth가 여러 곳에 흩어지면 어떤 문제가 생기는지 먼저 보자.// ❌ 안티패턴 — 같은 데이터를 두 곳에서 따로 관리struct ParentView: View { @State var isOn = false}struct ChildView: Vi.. 2026. 3. 8.
[SwiftUI] SwiftUI 레이아웃은 어떻게 동작하는가 UIKit에서는 frame을 직접 지정하거나 Auto Layout 제약을 걸어서 뷰의 크기와 위치를 결정했다.SwiftUI는 다르다. 개발자가 크기를 직접 명령하는 대신, 부모와 자식이 협상해서 레이아웃을 결정한다.이 글에서는 SwiftUI 레이아웃의 3단계 프로세스와, 뷰가 크기를 결정하는 두 가지 성질인 Hugging과 Expanding을 정리한다. 레이아웃 프로세스SwiftUI의 레이아웃은 부모 → 자식 → 부모 순서로 진행된다.1. 부모가 제안 (Propose)2. 자식이 결정 (Choose) 3. 부모가 배치 (Place)1단계. 부모가 자식에게 "제안 크기"를 제공한다부모 뷰는 자식 뷰에게 "너는 이 크기 안에 들어올 수 있어"라고 제안한다.중요한 건 이게 강제가 아닌 제안(Proposal).. 2026. 3. 6.
[SwiftUI] SwiftUI의 뷰는 왜 struct이고, some View란? SwiftUI를 처음 시작하면 자동으로 생성되는 코드가 있다.struct ContentView: View { var body: some View { Text("Hello, world!") }}익숙해서 그냥 넘기기 쉽지만, 이 코드 안에는 SwiftUI의 핵심 철학이 담겨 있다.struct를 왜 쓰는지, View 프로토콜은 왜 채택하는지, var body는 무슨 의미인지, 그리고 some은 뭔지 한 줄씩 뜯어보자. 1. 왜 class가 아닌 struct인가?UIKit에서는 뷰를 UIView를 상속한 class로 만들었다. 그런데 SwiftUI는 왜 struct를 택했을까?값 타입 vs 참조 타입struct는 값 타입(Value Type)이다. 복사하면 완전히 독립된 복사본이 생긴다... 2026. 3. 6.
[BLE] CoreBluetooth, ESC/POS 프로토콜 https://developer.apple.com/documentation/corebluetooth/ Core Bluetooth | Apple Developer DocumentationCommunicate with Bluetooth low energy and BR/EDR (“Classic”) Devices.developer.apple.com Bluetooth는 근거리(일반적으로 10~100m 이내)에서 무선으로 데이터를 주고받기 위한 단거리 무선 통신 기술Bluetooth의 개념2.4GHz 대역의 무선 주파수를 사용해서 스마트폰, 컴퓨터, 헤드셋, 프린터 등 다양한 디바이스끼리 케이블 없이 데이터를 교환할 수 있게 해주는 표준 기술장점저전력(특히 BLE)저렴한 비용자동 페어링다양한 기기 간 통신 지원(음.. 2026. 2. 19.
[Architecture] MVI 단방향 데이터 흐름을 기반으로 한 아키텍처 패턴사용자의 의도(Intent)를 통해서만 상태를 변경할 수 있고, 상태는 항상 하나의 경로로만 흐름“상태 변경 경로를 하나로 제한한다”가 핵심MVVM에서 여러 곳에서 상태가 변경되어 추적이 어려운 문제를 해결함TCA는 사실 MVI의 개념을 Swift/SwiftUI에 맞게 발전시킨 거임. 구조가 거의 동일함각 계층의 역할Intent사용자의 의도“이런 일을 하고 싶다”는 이벤트버튼 탭, 화면 진입, 텍스트 입력 등Model앱의 상태(State)를 관리Intent를 받아서 상태를 변경하는 유일한 곳MVVM의 데이터 모델이 아니라 상태 관리자에 가까움ViewState를 받아서 화면에 그리기만 함직접 상태를 변경하지 않음View가 state를 직접 수정하지 못하고(pr.. 2026. 2. 19.
[Architecture] MVC https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html Model-View-ControllerRetired Document Important: This document may not represent best practices for current development. Links to downloads and other resources may no longer be valid. Model-View-Controller The Model-View-Controller (MVC) design pattern assigns objects in an apdeveloper.apple... 2026. 2. 19.