TAGS

주제로 글을 찾습니다

Tech, Domain, Journal 글에 붙은 공통 태그를 모았습니다.

채팅을 운송 오더로 바꾸는 파이프라인

Tech

이 작업에서 저는 서버 분석 API, intent 판정과 초안 변환 호출, 오더 후보 저장, 메시지 처리 상태 관리를 맡았습니다. 이 글은 2026년 10월 당시의 구현을 돌아보며 정리했습니다. 서버 측 공통 오더 식별자로의 전환은 원고를 정리할 때까지 구현되지 않은 상태였습니다.

  • decision API
  • structured output
  • OpenAI Responses
  • 해시 멱등키
  • 동시성

if(kakao) 26 후기

Journal

if(kakao)26에서 AI 시대의 개발자 역할을 생각하고, 카카오에 다니는 후배와 각자의 일을 나눈 날.

  • if(kakao)26
  • 카카오
  • AI
  • 후기

후기 탐색을 주문 시작으로 잇기 위한 운송후기 탭 실험

Tech

운송후기 탭 실험에서 체크아웃 시작은 늘었지만 구매 전환 차이는 확인되지 않았습니다. 지도·검색·사진 필터의 효과를 어디까지 해석할 수 있었는지 첫 DRI의 판단과 함께 정리했습니다.

  • A/B 테스트
  • 제품 실험
  • 전환율
  • WKWebView
  • iOS
iOS 개발 필수 기본기푸시 알림 생명주기

푸시 알림 생명주기

Domain

"FCM을 쓰면 APNs가 필요 없다"는 오해가 흔하다. iOS 푸시는 어떤 경우에도 APNs를 거친다. FCM은 서버에서 APNs까지의 구간을 감싸 주는 편의 레이어이고, 기기에 메시지를 꽂는 건 언제나 APNs다.

  • iOS
  • Push
  • APNs
  • FCM
  • UNUserNotificationCenter
iOS 개발 필수 기본기딥링크와 앱 라우팅

딥링크와 앱 라우팅

Domain

웹에서 https://shop.example.com/product/42를 누르면 상품 화면으로 간다. 딥링크는 같은 일을 앱에서 하는 링크다. 푸시·알림톡·광고를 눌렀을 때 홈이 아니라 그 화면으로 곧장 보낸다. 중간 화면을 하나 더 거치게 두면 그 사이에서 이탈이 난다.

  • iOS
  • Deeplink
  • URLScheme
  • UniversalLink
  • DeferredDeepLink

차주 위치를 실시간으로 공유하는 운송 추적

Tech

배민·우버처럼 차주 위치를 지도에서 실시간으로 공유하는 운송 추적을, 폴링·SSE·WebSocket 중 무엇을 어디에 쓸지 고르고, 끊겨도 화주가 못 느끼게 재연결과 경로 이탈·지도 렌더까지 설계한 기록.

  • 실시간
  • WebSocket
  • 폴링
  • SSE
  • 재연결

WWDC26 워치파티 후기

Journal

6월 8일 밤 시작해 다음 날 새벽까지 이어진 WWDC26 워치파티 기록.

  • WWDC26
  • Apple
  • iOS
  • 워치파티
  • 후기
리액트 네이티브 백과사전react-native-bootsplash 내부 동작 원리

react-native-bootsplash 내부 동작 원리

Domain

OS LaunchScreen과 RN 첫 paint 사이의 공백을 메우는 방법.

  • React Native
  • BootSplash
  • LaunchScreen
  • Cold Boot
  • iOS
애플 플랫폼 백과사전WKWebView와 Android WebView가 화면을 그리는 방식의 차이

WKWebView와 Android WebView가 화면을 그리는 방식의 차이

Domain

같은 페이지가 iOS WKWebView에서는 fragment 앵커 점프 후 위쪽이 빈 화면으로 보이고 Android WebView에서는 멀쩡히 그려진다. 두 엔진의 tile/painting 모델을 따라가며 왜 한쪽에서만 일어나는지 정리한다.

  • iOS
  • Android
  • WKWebView
  • WebView
  • WebKit
애플 플랫폼 백과사전WWDC20 10040

Data Essentials in SwiftUI (WWDC20 10040)

Domain

Curt Clifton·Luca Bernardi·Raj Ramamurthy가 SwiftUI의 데이터 소유권·source of truth·@State/@StateObject/@ObservedObject·view life cycle을 한 번에 정리한 세션. 내용·코드·맥락을 한국어로 재구성한다.

  • iOS
  • SwiftUI
  • State
  • Binding
  • StateObject
애플 플랫폼 백과사전WWDC21 10022

Demystify SwiftUI (WWDC21 10022)

Domain

Matt Ricketson·Luca Bernardi·Raj Ramamurthy의 대표 세션. identity·lifetime·dependencies 세 축으로 SwiftUI의 업데이트 규범을 체계화한다. dependency graph가 곧 SwiftUI의 render tree라는 것까지.

  • iOS
  • SwiftUI
  • Identity
  • Lifetime
  • Dependencies
애플 플랫폼 백과사전WWDC23 10160

Demystify SwiftUI Performance (WWDC23 10160)

Domain

SwiftUI 앱이 느려지는 원인을 진단하는 법. printChanges로 의존성 추적, body 안의 work 제거, List/Table의 identity 수집 메커니즘까지 — 2021 Demystify가 이론이라면 이 세션은 최적화 매뉴얼이다.

  • iOS
  • SwiftUI
  • Performance
  • printChanges
  • List
애플 플랫폼 백과사전SwiftUI의 Identity · Lifetime · Dependencies

SwiftUI의 Identity · Lifetime · Dependencies

Domain

Omar Radwan의 SwiftUI Under the Hood 번역. Demystify SwiftUI 세션(WWDC21 #10022 · WWDC23 #10160)의 세 기둥인 identity·lifetime·dependencies를 코드 예제와 함께 정리한다.

  • iOS
  • SwiftUI
  • Identity
  • Lifetime
  • Dependencies
애플 플랫폼 백과사전WWDC23 10149

Discover Observation in SwiftUI (WWDC23 10149)

Domain

Swift 5.9의 @Observable 매크로는 ObservableObject의 구조적 한계를 뒤집는다. body가 실제로 읽은 property만 추적하는 granular tracking 메커니즘과, @State·@Environment·@Bindable 세 개로 단순화된 property wrapper까지.

  • iOS
  • SwiftUI
  • Observable
  • ObservableObject
  • Bindable
애플 플랫폼 백과사전A Day in the Life of a SwiftUI View

A Day in the Life of a SwiftUI View

Domain

SwiftUI의 view tree → render tree 변환, .task 재실행 문제와 .id/.task(id:)의 트레이드오프, proposal-reporting 레이아웃 시스템, environment와 preferences의 방향성을 그림 100여 장으로 풀어낸 Chris Eidhof의 강연 정리.

  • iOS
  • SwiftUI
  • RenderTree
  • AttributeGraph
  • Layout
애플 플랫폼 백과사전Variadic Views in SwiftUI

Variadic Views in SwiftUI

Domain

VStack 안에 여러 뷰를 넣으면 SwiftUI는 그걸 어떻게 들고 있을까. TupleView·_VariadicView.Tree·UnaryViewRoot/MultiViewRoot의 구분, 그리고 List가 행 사이에 Divider를 끼워 넣을 수 있는 이유까지.

  • iOS
  • SwiftUI
  • VariadicView
  • TupleView
  • ViewBuilder
애플 플랫폼 백과사전RxSwift에서 Combine으로 넘어가며 정리한 것들

RxSwift에서 Combine으로 넘어가며 정리한 것들

Domain

- 값의 변화를 시간 축 위의 스트림으로 다루고, 스트림에 변환을 연쇄 적용해 결과 스트림을 얻는 방식 - 명령형: "지금의 값을 꺼내 계산한다" - 반응형: "값이 바뀔 때마다 어떻게 이어지는지 미리 정의해 둔다" - 목적: 수동 구독·콜백·상태 동기화가 중첩되며 생기는 복잡도를 값의 변화 자체에 위임

  • iOS
  • Swift
  • RxSwift
  • Combine
  • 반응형 프로그래밍
애플 플랫폼 백과사전SwiftUI의 내부 동작 원리

SwiftUI의 내부 동작 원리

Domain

View tree, Attribute Graph, _UIHostingView까지 — SwiftUI가 선언형 뷰를 실제 UIKit·Core Animation 위에 매핑하는 내부 구조를 따라간다.

  • iOS
  • SwiftUI
  • CoreAnimation
  • CATransaction
  • AttributeGraph
애플 플랫폼 백과사전iOS 앱 샌드박스와 Extension 정리

iOS 앱 샌드박스와 Extension 정리

Domain

- iOS 앱은 모두 샌드박스 안에서 동작. 다른 앱·시스템 자원에 임의 접근 불가 - 목적: 보안 경계 + 리소스 사용 규제 - 격리 범위 - 파일 시스템: 앱마다 독립된 홈 디렉토리 - 네트워크: 자체 URLSession·캐시 - 메모리: 프로세스 단위 격리 - Keychain: 기본은 앱 전용. access group 명시 시에만 공유 - UserDefaults: 앱 번들 단위

  • iOS
  • App Sandbox
  • App Extension
  • Entitlements
  • App Group
애플 플랫폼 백과사전WKWebView의 내부 동작 원리

WKWebView의 내부 동작 원리

Domain

WKWebView를 쓰다 보면 비슷한 순간이 반복됩니다. 로그인 쿠키를 넣었는데 첫 요청에는 빠지고, JS 브리징은 언제나 completion이나 callback으로 돌아오고, 메모리 압박이 오면 앱은 살아 있는데 웹 화면만 하얗게 비어 버립니다.

  • iOS
  • WKWebView
  • WebKit2
  • JavaScriptCore
  • IPC
애플 플랫폼 백과사전UIKit의 내부 동작 원리

UIKit의 내부 동작 원리

Domain

Runloop, CATransaction, Core Animation layer tree 등 UIKit이 화면을 그리기까지의 내부 동작을 파이프라인 단계별로 정리한다.

  • iOS
  • UIKit
  • CoreAnimation
  • CATransaction
  • Runloop
애플 플랫폼 백과사전Alamofire 제대로 쓰기

Alamofire 제대로 쓰기

Domain

Alamofire는 Apple URLSession 위에 올라가는 Swift 네트워킹 프레임워크다. 기본 사용법(AF.request, responseDecodable)은 단순하지만, 실제 프로덕션 앱에서는 엔드포인트 관리, 인증 헤더 주입, 토큰 자동 갱신, 스트리밍, 업로드 등 고급 기능이 필요해진다.

  • iOS
  • Swift
  • Alamofire
  • 네트워킹
  • OAuth
애플 플랫폼 백과사전Kingfisher Under the Hood

Kingfisher Under the Hood

Domain

Kingfisher는 URLSession 위에 올라가는 Swift 이미지 로딩 라이브러리다. imageView.kf.setImage(with: url) 한 줄로 동작하지만, 그 한 줄 아래에는 다중 레이어 캐시, 비동기 다운로드 파이프라인, 프로세서 체인, 프리패칭, 재시도 전략이 맞물려 돌아간다.

  • iOS
  • Swift
  • Kingfisher
  • 이미지
  • 캐싱
TCA 실전TCA Under the Hood

TCA Under the Hood

Domain

TCA(The Composable Architecture)를 쓰면서 "왜 이렇게 동작하지?" 싶었던 순간들이 있었다. send가 동기인 것 같으면서도 Effect가 비동기고, 같은 액션을 두 번 보내면 경고가 뜨고, scope를 호출할 때마다 새 Store가 생기지 않는 것처럼 느껴지고.

  • iOS
  • Swift
  • TCA
  • Architecture
  • SwiftUI

URLProtocol과 Bonjour로 직접 만든 iOS 실시간 네트워크 디버거

Tech

센디 앱을 개발하면서 네트워크부터 의심해야 하는 순간이 자주 있었습니다. QA에서 올라오는 "API가 느려요" 리포트, 특정 화면에서만 재현되는 빈 응답 같은 문제는 대부분 네트워크 구간을 봐야 답이 나옵니다. 그런데 iOS에서 개발 중인 실기기의 요청을 바로 들여다보는 흐름이 생각보다 매끄럽지 않았습니다. Alamofire나 URLSession에 print 로깅을 달아 놔도 Xcode 콘솔에서 필요한 요청만 골라 읽기…

  • iOS
  • URLProtocol
  • URLSession
  • Alamofire
  • MethodSwizzling
애플 플랫폼 백과사전iOS 코드 서명 정리

iOS 코드 서명 정리

Domain

- 앱의 출처(등록된 개발자·조직)를 검증 - 서명 이후 코드 변조 여부 검증 - Push Notification · App Groups 같은 권한 사용 가능 앱 제한

  • iOS
  • CI/CD
  • CodeSigning
  • Certificate
  • ProvisioningProfile

GitHub Actions + Fastlane 기반 iOS 배포 자동화

Tech

기능을 만드는 시간보다 빌드를 기다리는 시간이 더 길게 느껴질 때가 있습니다. 코드 한 줄을 고쳐도 확인을 받으려면 앱을 새로 빌드해 전달해야 하고, 이 과정은 수정할 때마다 처음부터 다시 반복됩니다.

  • iOS
  • CI/CD
  • GitHubActions
  • Fastlane
  • Firebase

센디 iOS 앱에 React Native 얹기

Tech

센디는 iOS와 Android 앱을 각각 네이티브로 개발해 왔습니다. 새로운 기능이 추가되면 두 플랫폼에서 동일한 요구사항을 바탕으로 화면과 로직을 구현했습니다.

  • iOS
  • ReactNative
  • 브라운필드
  • 서브모듈
  • 심볼릭링크

Letus Go! 2025 가을 모임 후기

Journal

마루360에서 열린 Letus Go! 가을 모임에 다녀온 기록.

  • Letus Go
  • 개발자 모임
  • iOS
  • 후기
리액트 네이티브 백과사전React Native New Architecture의 내부 동작 원리

React Native New Architecture의 내부 동작 원리

Domain

React Native에서 버튼을 탭하면 무슨 일이 일어날까?

  • iOS
  • React Native
  • New Architecture
  • Fabric
  • JSI
리액트 네이티브 백과사전React Native 브라운필드 통합

React Native 브라운필드 통합

Domain

기존 앱에 RN 얹기.

  • iOS
  • React Native
  • Brownfield
  • TurboModule
  • JSI

CRM 캠페인에서 시작한 앱 진입 시스템 구축기 (1): 푸시 알림 수신과 클릭

Tech

앱 진입 시스템 구축기 1편. CRM 캠페인에서 사용한 Notification Service Extension 코드와 2025년 7월 기기 화면 녹화로 이미지 푸시 처리와 탭 이후 흐름을 정리.

  • Push Notification
  • Notification Service Extension
  • ColdStart
  • Rich Push
  • APNs

CRM 캠페인에서 시작한 앱 진입 시스템 구축기 (2): 여러 경로를 모으는 딥링크 라우팅

Tech

앱 진입 시스템 구축기 2편. CRM 캠페인에서 사용한 푸시·Universal Link·OneLink 세 진입 경로를 하나의 매칭 테이블로 모으고, 해석·매칭·내비게이션을 타입별로 분리해 새 캠페인을 테이블 한 줄로 끝낸 라우팅 설계.

  • Deeplink
  • Universal Link
  • URI Scheme
  • AppsFlyer
  • OneLink

CRM 캠페인에서 시작한 앱 진입 시스템 구축기 (3): 웹뷰와 네이티브를 잇는 브릿지

Tech

앱 진입 시스템 구축기 3편. CRM 이벤트 웹뷰 CTA를 네이티브 화면으로 잇는 단일 브릿지 채널과 enum 강제 디코딩으로 무반응을 없애고, 2-depth 웹뷰 스택을 네이티브 네비게이션으로 관리한 기록.

  • WKWebView
  • JSBridge
  • WKScriptMessageHandler
  • 웹뷰 스택
  • Universal Link
리액트 네이티브 백과사전React Native iOS 앱 부트스트랩

React Native iOS 앱 부트스트랩

Domain

@main에서 첫 화면까지.

  • iOS
  • React Native
  • Hermes
  • JSI
  • Thread

WWDC25 워치파티 후기

Journal

부산에서 올라와 WWDC25 워치파티에 참석하고 새벽 기차로 돌아온 기록.

  • WWDC25
  • Apple
  • iOS
  • 워치파티
  • 후기

센디 결제카드 스캐너 개발기 (2): 카메라 없이 검증하는 모듈 설계

Tech

카메라와 촬영 화면, 카드 인식 기능을 하나의 모듈에 담고 영상과 합성 이미지로 검증하는 구조를 정리합니다. 입력을 교체하는 지점과 테스트별 확인 범위를 나누고, 실제 기기에 남겨 둔 검증도 설명합니다.

  • iOS
  • SPM
  • 모듈화
  • 테스트
  • CGImage

센디 결제카드 스캐너 개발기 (1): 카메라 프레임에서 카드 정보 추출

Tech

카드 번호를 직접 입력하는 부담을 줄이기 위해 구현한 카메라 스캐너입니다. 프레임 수집과 안내 영역 크롭, Vision 텍스트 인식부터 사용자 확인 화면까지의 처리 과정을 설명합니다.

  • iOS
  • AVFoundation
  • VideoToolbox
  • Vision
  • OCR

제대로 알고 싶었던 한 해 (2024 회고)

Journal

혼자 공부해 온 iOS 지식을 돌아보고, 새싹 과정에서 배우고 설명하며 빈틈을 채운 2024년 회고.

  • 회고
  • iOS
  • 새싹
  • 2024
애플 플랫폼 백과사전AttributeGraph 풀어 보기

AttributeGraph 풀어 보기

Domain

Apple 이 숨겨 놓은 AttributeGraph 프레임워크를 lldb 로 직접 찔러 본 기록. AG::Graph::print() 심볼을 GraphViz 로 덤프해 state 변경 → dirty 전파 → lazy evaluation → RootDisplayList 갱신까지 실제 그래프로 확인한다. subgraph 가 view tree 의 동적 구조를 어떻게 포장하는지까지.

  • iOS
  • SwiftUI
  • SwiftUI Internals
  • AttributeGraph
  • Debugging

처음 열린 KWDC 2023

Journal

처음 열린 KWDC 2023에 참석해 TCA와 Apple 플랫폼 이야기를 듣고 개발자들을 만난 기록.

  • KWDC
  • TCA
  • localization
  • Apple
  • 컨퍼런스
TCA 실전forEach와 IdentifiedArray, 바인딩 변수

컬렉션과 바인딩: forEach와 IdentifiedArray, 바인딩 변수

Domain

앞 장까지로 화면 하나와 화면 사이 전환을 다뤘다. 남은 건 화면 안쪽에서 자주 나오는 두 패턴이다. 하나는 목록이고, 하나는 폼이다.

  • iOS
  • TCA
  • forEach
  • IdentifiedArray
  • 바인딩
TCA 실전iOS 15 대응부터 iOS 16 Stack까지

화면 전환: iOS 15 대응부터 iOS 16 Stack까지

Domain

화면이 하나일 때는 1장의 단방향 흐름으로 충분하다. 문제는 화면이 여러 개가 되면서 시작된다. 목록에서 상세로 들어가고, 거기서 편집 시트를 띄우고, 저장하면 두 단계를 한 번에 닫는다. 이런 전환을 뷰 코드에서 명령형으로 밀고 당기면, 지금 어느 화면이 떠 있는지가 다시 여기저기 흩어진다. 1장에서 겨우 좁혀 놓은 추적 가능성이 화면 전환에서 무너지는 것이다.

  • iOS
  • TCA
  • 네비게이션
  • NavigationStack
  • LinkNavigator
iOS 개발 필수 기본기배포의 원리와 패키지 관리

배포의 원리와 패키지 관리

Domain

앱을 만드는 내내 Xcode의 실행 버튼 하나로 빌드하고 설치했다. 그런데 이 버튼이 실제로 무슨 일을 하는지는 오래 몰랐다. 소스 코드가 어떻게 실제 기기에서 도는 앱이 되고, 왜 아무 기기에나 깔리지 않는지가 불투명했다. 이걸 이해하려면 버튼 한 번으로 뭉뚱그려진 과정을 명령줄에서 손으로 밟아 보는 게 가장 빠르다.

  • iOS
  • xcodebuild
  • ipa
  • CocoaPods
  • 코드서명
TCA 실전의존성 관리와 테스트

의존성 관리와 테스트

Domain

1장의 Effect 안에서 apiClient.fetchItems()를 불렀다. 문제는 이 한 줄이 테스트를 통째로 어렵게 만든다는 데 있다. 테스트가 진짜 서버를 부르면 네트워크 상태에 따라 결과가 달라지고, 느리고, 서버가 특정 상황을 돌려주게 만들 수도 없다. 현재 시간, 랜덤 값, 파일 시스템도 같은 문제를 갖는다. 결과가 바깥 환경에 따라 달라지는 코드는 그대로는 테스트할 수 없다.

  • iOS
  • TCA
  • 의존성주입
  • 테스트
  • Dependencies
iOS 개발 필수 기본기로컬 데이터 저장의 선택지

로컬 데이터 저장의 선택지

Domain

앱을 만들다 보면 데이터를 기기에 남겨야 하는 순간이 온다. 다크 모드 설정, 마지막으로 본 화면, 로그인 토큰, 다운로드한 이미지, 오프라인에서도 봐야 할 목록까지 종류가 제각각이다. 처음엔 이 모든 걸 UserDefaults에 넣으려다 문제를 겪었다. 이미지를 통째로 넣었더니 앱이 켜질 때마다 느려졌고, 목록을 넣었더니 일부만 골라 읽는 게 불가능했다.

  • iOS
  • UserDefaults
  • FileManager
  • CoreData
  • 저장소
TCA 실전State·Action·Reducer·Store와 단방향 흐름

State·Action·Reducer·Store와 단방향 흐름

Domain

SwiftUI로 화면 몇 개를 만들어 보면 상태 관리가 곧 벽이 된다. 작은 뷰는 @State로 충분하지만, 화면이 커지면 여러 뷰가 같은 값을 공유해야 하고 @ObservedObject, @EnvironmentObject가 섞여 들어온다. 문제는 값을 바꾸는 경로가 정해져 있지 않다는 데 있다. 어떤 버튼이 어디의 상태를 직접 고치고, 그 변화가 또 다른 상태를 건드리기 시작하면 "지금 이 값이 왜 이렇게 됐는지"를 되…

  • iOS
  • TCA
  • SwiftUI
  • 상태관리
  • 단방향
SwiftUI 기본실전 구성 팁

실전 구성 팁

Domain

기본기를 익히고 실제 화면을 만들기 시작하면 곧 다른 종류의 어려움을 만난다. 문법이 아니라 구조의 문제다. body 안에 뷰가 쌓이면서 수십, 수백 줄이 되고, 어디를 고쳐야 할지 눈에 안 들어온다. 조건 분기와 스택이 겹치면 들여쓰기만 깊어진다.

  • iOS
  • SwiftUI
  • ViewBuilder
  • renderingMode
  • LazyVStack
애플 플랫폼 백과사전SwiftUI 의 diffing algorithm

SwiftUI 의 diffing algorithm

Domain

SwiftUI 가 React 처럼 identifier 나 shortest-edit-script 없이도 대부분의 경우 view 변화를 모호함 없이 판별하는 이유. 비결은 정적 타입. TupleView<(Text, _ConditionalView<A, B>)> 자체가 구조를 드러내므로 같은 타입끼리만 비교하면 된다. Swift 코드로 직접 재구성해 본다.

  • iOS
  • SwiftUI
  • SwiftUI Internals
  • Diffing
  • ViewBuilder
SwiftUI 기본상태로 화면을 제어한다

상태로 화면을 제어한다

Domain

UIKit에서 얼럿을 띄우려면 present(alert, animated: true)를 호출했다. 화면 전환도, 액션 시트도 전부 "지금 띄워라"라고 명령하는 함수 호출이었다. SwiftUI로 넘어와 처음 얼럿을 띄우려 할 때 이 함수를 찾다가 막힌다. 그런 함수가 없기 때문이다.

  • iOS
  • SwiftUI
  • State
  • Alert
  • Sheet
애플 플랫폼 백과사전SwiftUI 의 render loop

SwiftUI 의 render loop

Domain

body 평가와 실제 화면 렌더링은 같지 않다. onAppear 가 왜 깜빡임을 만들지 않는지, preference key 기반 커스텀 layout 에서 body 가 두 번 평가돼도 왜 첫 번째는 화면에 닿지 않는지 — CFRunLoop 의 beforeWaiting observer 와 암묵적 CATransaction 의 관계까지 내려가 설명한다.

  • iOS
  • SwiftUI
  • SwiftUI Internals
  • CFRunLoop
  • CATransaction
SwiftUI 기본데이터 흐름의 두 원칙

데이터 흐름의 두 원칙

Domain

선언형 감각을 잡고 나면 곧바로 막히는 지점이 있다. 상태를 담는 방법이 하나가 아니라는 것이다. @State, @Binding, @ObservedObject, @StateObject, @EnvironmentObject가 줄줄이 나오는데, 처음에는 무엇을 언제 써야 하는지 감이 안 온다. 아무거나 골라 쓰다가 화면이 갱신되지 않거나, 반대로 값이 자꾸 초기화되는 문제를 겪는다.

  • iOS
  • SwiftUI
  • State
  • Binding
  • ObservableObject
애플 플랫폼 백과사전SwiftUI 에서 escaping closure 를 쓰지 말아야 하는 이유

SwiftUI 에서 escaping closure 를 쓰지 말아야 하는 이유

Domain

커스텀 container view 를 만들 때 content 를 @escaping closure 로 받을지, 초기화 때 바로 평가해서 view 로 저장할지. 겉보기엔 closure 쪽이 더 효율적이지만 실제로는 @State 최적화와 memoization 이 동시에 깨진다. Rens Breur 가 왜 view 는 이미 함수인지부터 짚고 시작한다.

  • iOS
  • SwiftUI
  • SwiftUI Internals
  • ViewBuilder
  • Memoization
iOS 개발 필수 기본기MVC와 MVVM

아키텍처 패턴과 선택 (MVC와 MVVM)

Domain

처음 몇 개 화면은 아키텍처를 몰라도 만들어진다. ViewController 하나에 화면 그리는 코드, 네트워크 호출, 데이터 가공, 화면 전환을 다 몰아넣어도 돌아가긴 한다. 문제는 그 화면이 커질 때 생긴다. 목록을 불러오고, 로딩 상태를 보여 주고, 검색을 걸고, 에러를 처리하고, 셀을 탭하면 상세로 넘어가는 화면 하나가 금세 수백 줄이 된다. 어디를 고쳐야 할지 찾는 데만 한참 걸리고, 한 곳을 고치면 엉뚱한 데가…

  • iOS
  • 아키텍처
  • MVC
  • MVVM
  • ViewController
UIKit로 화면 만들기타깃액션과 네트워크 데이터로 화면 채우기

타깃액션과 네트워크 데이터로 화면 채우기

Domain

지금까지 화면을 그렸지만, 아직 사용자 입력을 받지 못했다. 버튼을 눌러도 아무 일이 안 일어난다. 입력을 코드에 연결하는 UIKit의 방식이 타깃액션(target-action)이다.

  • iOS
  • UIKit
  • 타깃액션
  • selector
  • Codable
SwiftUI 기본명령형에서 선언형으로

명령형에서 선언형으로

Domain

UIKit을 쓰다 SwiftUI로 넘어오면 가장 먼저 찾게 되는 것이 "화면을 다시 그리는 함수"다. UIKit에서는 그게 일이었기 때문이다. 카운트가 하나 늘면 countLabel.text를 새로 대입하고, 버튼을 잠가야 하면 button.isEnabled = false를 부른다. 데이터가 바뀔 때마다 그 변화를 화면에 반영하는 코드를 사람이 직접 써 준다. 이게 명령형 방식이다.

  • iOS
  • SwiftUI
  • 선언형UI
  • UIKit
  • State
UIKit로 화면 만들기주요 컴포넌트와 MVC

주요 컴포넌트와 MVC

Domain

지금까지 뷰를 붙이고, 화면을 넘기고, 배치를 잡는 뼈대를 봤다. 이제 그 위에 올릴 실제 부품을 다룬다. iOS 화면 대부분은 몇 가지 표준 컴포넌트의 조합이다. 글자를 보여 주는 UILabel, 탭을 받는 UIButton, 입력을 받는 UITextField, 그림을 그리는 UIImageView, 그리고 목록을 그리는 UITableView다.

  • iOS
  • UIKit
  • UITableView
  • MVC
  • delegate
iOS 개발 필수 기본기앱은 어디서 시작하는가

앱은 어디서 시작하는가

Domain

C 프로그램에는 main 함수가 있고 거기서 실행이 시작된다는 걸 학부에서 배웠다. 그런데 처음 만든 iOS 프로젝트를 아무리 뒤져도 main이라 부를 만한 곳이 없었다. AppDelegate가 있고 SceneDelegate가 있는데, 둘 중 무엇이 먼저 도는지, 애초에 이 코드를 누가 부르는지가 불투명했다.

  • iOS
  • UIKit
  • AppDelegate
  • SceneDelegate
  • main
Swift 언어 기본옵셔널과 안전한 nil 처리

옵셔널과 안전한 nil 처리

Domain

다른 언어에서 null은 그냥 아무 참조에나 들어갈 수 있는 값이었다. 그래서 값이 없는데 접근하려다 터지는 사고를 늘 조심해야 했다. Swift를 처음 잡았을 때 변수 타입 뒤에 붙는 물음표가 낯설었다. String과 String?이 왜 다른 타입인지, nil을 넣으려면 왜 굳이 물음표를 붙여야 하는지 이해가 안 갔다.

  • iOS
  • Swift
  • Language
  • 옵셔널
  • 옵셔널바인딩

팀원과 팀장으로 치른 로봇대회

Journal

2020년에는 팀원으로, 이듬해에는 팀장으로 임베디드SW경진대회에 참가해 최우수상을 받기까지의 기록.

  • 회고
  • 임베디드
  • 대회
  • 팀장
Swift 언어 기본메모리 관리와 ARC

메모리 관리와 ARC

Domain

가비지 컬렉터가 도는 언어를 먼저 접했던 터라, Swift에서 메모리를 언제 어떻게 지우는지가 처음엔 막막했다. free를 직접 부르는 것도 아닌데 메모리가 새지 않는다니 신기했고, 반대로 분명히 화면을 닫았는데 그 화면 객체의 deinit이 안 불리는 걸 보고는 당황했다. 다 쓴 객체가 메모리에 그대로 남아 있었다.

  • iOS
  • Swift
  • Language
  • ARC
  • 순환참조
UIKit로 화면 만들기오토레이아웃과 코드 기반 UI

오토레이아웃과 코드 기반 UI

Domain

앞 장까지는 뷰의 위치를 frame에 좌표 숫자로 직접 넣었다. 작은 예제에선 잘 되지만, 실제 앱에서는 금방 깨진다. iPhone SE의 좁은 화면과 큰 Pro Max의 넓은 화면은 폭이 다르고, 가로로 돌리면 또 달라진다. "왼쪽에서 320만큼" 같은 절대 좌표는 특정 기기에서만 맞는다.

  • iOS
  • UIKit
  • AutoLayout
  • 제약
  • 우선순위
Swift 언어 기본값 타입과 참조 타입

값 타입과 참조 타입

Domain

입문기에 가장 크게 데였던 지점이다. 데이터 묶음을 만들 때 struct로 만들지 class로 만들지 감이 없었다. 둘 다 프로퍼티와 메서드를 담을 수 있으니 겉보기엔 비슷했다. 그런데 복사해서 한쪽을 고쳤더니, 구조체는 다른 쪽이 멀쩡한데 클래스는 다른 쪽도 같이 바뀌었다. 같은 문법으로 만든 것 같은데 결과가 정반대라 한참을 헤맸다.

  • iOS
  • Swift
  • Language
  • 구조체
  • 클래스
UIKit로 화면 만들기뷰컨트롤러 생명주기와 화면 전환

뷰컨트롤러 생명주기와 화면 전환

Domain

앞 장에서 화면은 뷰의 트리라고 했다. 그런데 그 트리를 누가 만들고, 데이터를 채우고, 화면이 나타나고 사라질 때 뒷정리를 하는가. 그 담당자가 UIViewController다. iOS에서는 화면 하나에 뷰컨트롤러 하나를 대응시키는 것이 기본이다. 로그인 화면, 목록 화면, 상세 화면이 각각 별도의 뷰컨트롤러다.

  • iOS
  • UIKit
  • UIViewController
  • 생명주기
  • 화면전환
UIKit로 화면 만들기뷰와 뷰 계층

뷰와 뷰 계층

Domain

iOS 화면을 처음 뜯어볼 때 가장 도움이 됐던 관점은 이거였다. 눈에 보이는 모든 것은 결국 사각형 하나다. 버튼도 사각형, 레이블도 사각형, 이미지도 사각형이다. 이 사각형 하나하나가 UIView이고, 화면은 이 뷰들이 서로 겹치고 포개진 결과다.

  • iOS
  • UIKit
  • UIView
  • 뷰계층
  • 좌표계
Swift 언어 기본함수는 1급 객체다

함수는 1급 객체다

Domain

Swift를 배우기 전에 다뤘던 언어에서 함수는 그냥 "호출하는 것"이었다. 그런데 Swift 코드를 읽다 보니 함수를 변수에 대입하고, 다른 함수의 인자로 넘기고, 함수가 함수를 돌려주는 장면이 계속 나왔다. sorted(by:)에 정렬 기준을 통째로 넘기는 코드를 처음 봤을 때, 저기 들어가는 게 값인지 코드인지 헷갈렸다.

  • iOS
  • Swift
  • Language
  • 클로저
  • 고차함수