일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- state
- date
- Network
- GCD
- 최적화
- WWDC
- arkit
- withAnimation
- RxSwift
- stateobject
- sheet
- UIKit
- 알고리즘
- ios
- gesture
- dataflow
- firebase
- CS
- Algorithm
- Concurrency
- swift
- Animation
- authentication
- SwiftUI
- combine
- iphone
- auth
- DateFormatter
- SwiftData
- async
- Today
- Total
목록swift (37)
XLOG
서버 개발자가 "UTC로 주고받자"고 했을 때...처음 서버 개발자와 협업할 때 "시간은 UTC로 주고받겠습니다"라는 말을 들었을 때의 제 반응은 이랬습니다."UTC? 왜 한국시간대가 아니지?"하지만 이유를 잘 몰라도 일단 규칙이니까 맞춰서 작업했죠. 그냥 서버에서 요구하는 형식으로 보내고, 받은 데이터를 화면에 표시하면 되는 거 아닌가 싶었어요.사이드 프로젝트에서 만난 현실의 벽사이드 프로젝트에서 반복 스케줄 기능을 구현하게 되었을 때, 시간의 복잡성을 본격적으로 체감했습니다. "매주 화요일 오후 3시에 알림" 같은 기능 말이죠.첫 번째 깨달음: Date는 절대 시점이다let now = Date()print(now) // 2024-01-15 05:30:00 +0000let formatter = Date..
왜 이 구조를 도입했나앱 기획이 바뀌고 기능이 추가될 때마다 navigationDestination, sheet, fullScreenCover가 군데군데 늘어나고, 상태 변수도 화면마다 따로 생기곤 합니다. 화면 수가 많아질수록 가독성은 떨어지고 실수가 늘죠.저는 “어떤 View에서든 안전하게 시트를 띄우고, 스택을 쌓고, 쉽게 닫을 수 있는 단일 API”를 목표로 라우터/코디네이터를 도입했습니다. 결과적으로 화면 전환 코드가 뷰 구현에서 분리되어 테스트 가능하고 확장 가능한 구조를 갖게 되었습니다.설계 목표관심사 분리: 화면 전환(네비게이션)은 뷰 로직에서 분리단일 소스: push/pop, present/dismiss를 한 곳에서 관리모달 독립성: 시트/풀스크린 내부도 자체 네비게이션을 가질 수 있게확..
최근 디버그 과정 중 continuation 쪽 문제를 해결하면서 내용을 한번 정리해두는게 좋다는 생각이 들어서 시작한 글입니다.swift의 async/await는 복잡한 비동기 코드를 깔끔하게 정리해주는 강력한 기능입니다. 그런데 기존의 콜백 기반 API를 어떻게 async 함수로 바꿀 수 있을까요? 그 때 등장하는 개념이 바로 continuation입니다.이 글에서는 continuation이란 무엇인지, 그리고 Swift에서 제공하는 관련 API들을 쉽게 설명해보겠습니다.🧠 continuation이란?간단히 말해, 중단된 함수의 흐름을 다시 이어줄 수 있는 객체입니다. Swift의 async 함수는 실행을 잠시 멈췄다가 다시 이어서 실행할 수 있어야 하는데, 그 주체가 continuation입니다...

1. 문제 및 원인요즘 Swift6 의 concurrency와 관련된 checking 이 강화되면서 Non-sendable 과 관련된 경고를 많이 보곤한다.SwiftData 가 나오고 SwiftUI 에서 View 내부에서 query 를 직접 입력해서 View에 바로 적용할 수 있으나 기존 Repository Pattern 을 쓰던앱에 아키텍쳐를 준수하기 위해 ModelContext 접근을 단일 Thread 를 보장하기 위해 ModelActor 를 활용했고, 이를 Repository 에 주입하여 DTO 로 변환을 하면 되겠다고 단순하게 생각했다.import Foundationimport SwiftData@Modelpublic class SwiftDataItem { @Attribute(.unique) ..
1. 문제public enum TransactionType: String, Codable, CaseIterable, Sendable { case income = "income" case fixedExpense = "fixedExpense" case variableExpense = "variableExpense"}@Modelfinal class Category { @Attribute(.unique) var id: UUID var name: String var orderIndex: Int var transactionType: TransactionType var isActive: Bool @Relationship(deleteRule: .cascade, inver..
한번씩 하려다보면 항상 검색을 해야해서 정리해보았다...1. Date - 기본 날짜/시간 타입Date는 Swift의 핵심 날짜/시간 타입으로, Unix 타임스탬프(1970년 1월 1일 00:00:00 UTC부터의 초)를 기반으로 한다.// 현재 시간let now = Date()// 특정 시간 생성let specificDate = Date(timeIntervalSince1970: 1640995200) // 2022-01-01 00:00:00 UTC// 상대적 시간 생성let oneHourAgo = Date(timeIntervalSinceNow: -3600)let tomorrow = Date(timeIntervalSinceNow: 86400)2. TimeInterval - 시간 간격TimeInterval은 ..
1. 배경회사에서 보행자 네비게이션 기능을 개발할 때 실시간 나의 위치가 경로상 어디에 위치하는지를 update 해줘야 했다. 보행자 경로 특성상 경로와 상관없이 지름길을 이용하기 쉽기에 순서와 상관없이 계산을 해야했다. 처음엔 LinearSearch 를 사용해 전체 coordinates 와의 거리를 계산하였다. 3km ~ 5km 의 경로를 테스트하며 UI 업데이트에 큰 무리는 없었으나, 연산량을 줄이면 배터리 및 성능의 이점을 가져올 수 있을거라 판단하여 확인하던 중 KD Tree 를 알게 되어 도입하게 되었다.2. KD Tree 란?KD Tree(K-Dimensional Tree)는 공간상의 점들을 빠르게 검색하기 위해 설계된 자료구조다. 내 경우는 경로가 2차원 (x, y) 좌표로 구성되어 있었고,..

Accessibility 를 공부하다가 보니 흔하게 사용하는 TextField 에서 음성입력 버튼이 없다는 걸 깨달았다. searchable 로 navigation bar 에 search controller 를 추가하더라도 없었다. 물론 키보드가 올라오면 음성입력할 수 있는 버튼이 있지만, 가장 최하단에 있어서 접근하는 것이 여간 불편한 일이라는 걸 깨달았다.해당 코드는에서는 AVAudioEngine 을 사용할 계획이다. 1. 권한 설정info.plist 에 마이크 사용 및 음성 인식 사용 권한 요청을 추가해 준다.2. STTManager 정의2-1 권한 요청 (Combine 으로 진행)import Foundationimport AVFoundationimport Speechfinal class STTMa..
하다보니 좌표를 전송해야할 필요가 생겼다. 하지만 나한테 주어진 데이터 크기의 제한이 있었다. 그래서 Google Map APi 에서 인코딩된 폴리라인에 관한 내용을 확인하고 적용하려고 했다.구글에서 얘기하는 인코딩된 Polyline해당 알고리즘은 손실이 있는 압축 알고리즘이다. 하지만 그 손실로 발생하는 오차를 최소화 하여 진행된다.좌표값은 위도(Double), 경도(Double) 로 이루어져 있다. 게다가 Polyline 은 이 위도의 배열로 구성되어 있다. 단순한 핵심 Point 뿐만이 아닌 지도상에 도로의 형태에 맞게 각도를 주기 위해 포인트와 포인트 사이에도 많은 좌표가 들어간다.이를 효율적으로(데이터의 오차는 적고, 압축율은 높게) 전달하기 위핸 알고리즘이다.10 진수 값에 1e5를 곱한 다음..

사이드 프로젝트를 진행하면서 Tree 형태의 데이터 구조를 만들어 사용했다.데이터는 SwiftData 를 사용해서 저장을 했으며 Model 은 Hashable 을 상속시켰다.그런데 데이터를 수정하고 나서 한번씩 Fatal error 가 발생했다.테스트를 더 해보긴 해야겠지만 찾아본 바로 원인은 Hashable을 충족하기 위해서 Equatable 또한 상속시켜야 한다. Hashable 이 Equatable 을 상속해야하는 이유는 HashValue 의 비교를 위해서인데, 여기서 내가 실수한 부분은 == 에 정의할 때 비교 연산을 Hash 함수에 사용한 Propertie 와 달라서 였다.예를 들면class Model { let id: UUID = UUID() let name: String let s..