ProtoBuf - 이게 뭔데 사람들은 환호성을 지를까?
·
SWIFT개발일지
우버나 카카오 네비 앱을 켜면 뭐가 보이나요? 지도 위에 내 위치가 표시되고, 주변 차량들이 실시간으로 움직이고, 예상 도착 시간이 계속 업데이트되죠.실시간 위치 서비스, 얼마나 많은 데이터가 오갈까요?가정을 하며 생각을 해볼게요.1초마다:내 GPS 위치 → 서버주변 운전자 10명의 위치 ← 서버예상 도착 시간 재계산 ← 서버도로 교통 상황 ← 서버한 명의 사용자만 봐도 이 정도인데, 동시에 100만 명, 아니 그 이상이 사용한다면? 🤯🧐 REST API로 실시간 위치를 추적한다면? -> 폴링 방식// 1초마다 서버에 요청Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in fetchDriverLocations { locations..
아 지겹다 복붙! Xcode 커스텀 템플릿 만들기
·
SWIFT개발일지
TCA로 프로젝트를 진행하면서 정말 지긋지긋했던 순간이 있어요. 새 Feature를 추가할 때마다:// 1. Feature 파일 만들고@Reducerpublic struct UserLoginFeature { @ObservableState public struct State: Equatable { // ... } // 이하 생략}// 2. View 파일 만들고public struct UserLoginView: View { @Bindable var store: StoreOf // ...}// 3. 파일명을 UserLogin으로 일일이 바꾸고...음 벌써 파일을 두개 만들었죠..?? 10번째쯤 되니까 너무 귀찮더라고요. 그래서 찾아본 게 Xcode 커스텀 템플릿이었..
BLE 완전 기초: CoreBluetooth를 이해하기 위한 필수 개념
·
SWIFT개발일지
블루투스 기기와 통신하는 iOS 앱을 만들려면 CoreBluetooth를 써야 해요. 그런데 막상 문서를 열어보면 Service, Characteristic, GATT... 생소한 용어들이 쏟아지죠. 이 글에서는 CoreBluetooth를 제대로 이해하기 위한 기초 지식을 다룰 거예요. BLE가 왜 탄생했고, 어떻게 동작하는지 알고 나면 CoreBluetooth를 다루는데 쉬울거라고 생각합니다:)Classic Bluetooth: 어떤 한계가 있었나?초기 블루투스는 "케이블을 없애자"라는 목표로 탄생했습니다. 지속적인 연결과 높은 데이터 전송률에 최적화됐죠.하지만 시대가 변했습니다. 에어팟, 혈당 측정기, 스마트워치 같은 센서 기기들이 폭발적으로 늘어났어요. 이런 기기들은 한 번 충전으로 며칠, 심지어 몇..
SwiftUI Instruments 하기
·
카테고리 없음
왜 SwiftUI 성능 디버깅이 어려울까?UIKit에서는 Time Profiler로 백트레이스 찍어보면 viewDidLoad에서 뭘 너무 많이 했나, tableView(_:cellForRowAt:)에서 뭘 건드리고 있나 단계별로 명령들을 볼 수 있었어요 그런데 SwiftUI로 넘어오면서 상황이 달라졌어요. 스크롤이 버벅대는데, Time Profiler를 열어보면 뭔가 알기가 어려워요. 선언형 패러다임의 양날의 검일 수도 있는데 이전과 달리 무엇에 집중하다 보니 어떻게는 뛰어넘어 그 어떻게를 보기 힘든거죠!!! 그래서 이번 WWDC26에서는 Instruments를 업데이트 해줬습니다:)(사실 원래도 있긴 했어요)먼저, SwiftUI의 렌더링 루프를 이해해야 해요요즘 아이폰은 대부분 120fps이기에 초당 ..
UIKit / SwiftUI에서는 무슨 디자인 패턴을 사용해야할까?
·
iOS
UIKit으로 개발할 때, 저는 Clean Architecture + MVVM + Coordinator 조합을 사용했어요. 사실 처음엔 누구나 그렇듯 MVC 패턴으로 시작했죠. 근데 이게... ViewController가 점점 비대해지더라고요. 전형적인 Massive View Controller 문제가 발생 🚨🚨첫 번째 시도: 상태를 Struct로 분리struct UserState { let name: String let email: String}class ViewController: UIViewController { private var state: UserState func updateUI() { nameLabel.text = state.name ..
URLSession 한 줄 뒤에 숨겨진 것들: DNS부터 전자기파까지
·
iOS
let task = URLSession.shared.dataTask(with: url) { data, response, error in // 응답 처리}task.resume()딸-깍 그런데 안에서는 어떤 동작이 이루어지는 지 아시나요? 이번 시간은 URLSession에 뭐가 있는지 아예 베이스에 대해서라기보다는 어떻게 동작하는지에 초점을 맞춰 글을 작성하려합니다.대신!! URLSession에 관해서는 아주 좋은 블로그를 추천해드리겠습니다:)https://codeisfuture.tistory.com/148 URLSession에 대한 에브리띵실제로는 URLSession은 Apple이 만든 거대한 URL Loading System의 하나인 거고 그 안에는 여러 라이브러리들이 있어요:) URL Loadi..
HTTP 캐싱(Etag & max-age) 그리고 iOS에서는?
·
iOS
왜 캐싱이 필요할까?대부분의 앱은 서버와 HTTP 통신으로 데이터를 가져와요. 그런데 이 과정에는 생각보다 큰 비용이 들어가죠.클라이언트(앱) → 네트워크 왕복 시간이 걸림서버 → 요청을 처리하느라 부하가 증가함사용자 → 데이터 사용량과 배터리를 소모함특히 이런 상황을 생각해봅시다.👉방금 받아온 데이터랑, 지금 또 요청하려는 데이터가 똑같다면? 업데이트된 정보도 없는데, 또 네트워크를 타는 건 이건 명백한 낭비죠입니다.이 문제를 해결하는 방법이 바로 HTTP 캐싱이에요.캐시는 어디에 저장되나?캐시는 어디에 저장되나?중간 서버에 캐시를 둔 구조CloudFront, Cloudflare 같은 CDNNginx, Varnish 같은 프록시요청이 캐시에 있으면 원 서버까지 안 가도 되지만, 여전히 네트워크는 타요..
전략패턴
·
디자인패턴
iOS 개발을 하다 보면 네트워크 요청을 하게 되고 URLRequest를 만들 때 이런 경우들이 있을 수 있죠:그냥 아무 데이터도 안 보내는 단순 GET쿼리 파라미터를 붙여서 GETJSON Body를 넣는 POST개발 초기에는 이런 케이스 몇개만 처리하면 충분합니다. 보통은 이렇게 enum으로 정의하고 switch로 분기했어요enum HTTPTask { case plain case query([String: String]) case json(Encodable)}그리고 URLRequestBuilder에서 이런 식으로…switch task { case .plain: ... case .query(let params): ... case .json(let body): ...}딱 여..
URLSession에 대한 에브리띵
·
iOS
실제로는 URLSession은 Apple이 만든 거대한 URL Loading System의 하나인 거고 그 안에는 여러 라이브러리들이 있어요:)URL Loading System의 전체 구조URL Loading System의 핵심 특징:비동기 처리: 모든 네트워크 작업이 백그라운드에서 수행되어 앱의 반응성 유지프로토콜 지원: HTTP, HTTPS, FTP, 파일, 그리고 커스텀 프로토콜까지 지원Cookie Storage (쿠키 관리부서 🍪)HTTPCookieStorage: 웹사이트 로그인 상태 유지, 사용자 설정 기억 등을 위한 쿠키 자동 관리HTTPCookie: 개별 쿠키 정보를 담는 컨테이너 역할Authentication & Credentials (보안 인증부서 🔐)URLProtectionSpace..