SwiftData 모델명 Tag가 빌드를 깨뜨리는 이유 (+ Xcode 16 .gitkeep 함정)

뭘 하려고 했냐면 문서 스캔 앱을 새로 시작했는데요. SwiftData로 Document와 Tag 모델을 만들고, 테스트를 먼저 작성하는 TDD로 진행하고 있었어요. 모델 코드는 심플했거든요: @Model class Tag { var name: String var color: String @Relationship(inverse: \Document.tags) var documents: [Document] } 여기까지는 문제없었어요. 빌드도 잘 되고. 첫 번째 삽질: Tag가 내 Tag가 아닌데요 테스트에서 FetchDescriptor를 쓰는 순간 터졌어요: let fetched = try context.fetch(FetchDescriptor<Tag>()) error: 'Tag' is ambiguous for type lookup in this context 처음엔 뭔 소린가 했는데요. SwiftUI에 이미 Tag라는 타입이 있더라고요. TabView나 Picker에서 선택 항목을 식별할 때 쓰는 그 Tag요. ...

2026년 4월 26일 · 3 분 · Young

iOS 음악 앱에서 다른 앱이 오디오를 빼앗아갈 때 대처하는 법

뭘 하려고 했냐면 Subsonic 기반 음악 스트리밍 앱을 만들고 있었는데요. AVPlayer로 백그라운드 재생까지 잘 되고 있었거든요. 그런데 테스트하다가 이상한 걸 발견했어요. 노래 재생하고 앱을 백그라운드로 보냄 YouTube 열어서 영상 재생 (노래 멈춤 — 여기까진 정상) YouTube 영상 닫음 앱에 돌아오면 일시정지 버튼이 보이는데 소리가 안 남 버튼을 누르면 재생이 시작되긴 하는데, 한 번 더 눌러야 하는 거예요. UI는 “재생 중"인데 실제론 멈춰있는 상태. 원인 AVPlayer 기반 앱은 다른 앱이 오디오 세션을 가져가면 시스템이 자동으로 AVPlayer를 pause시켜요. 문제는 이 사실을 앱에 알려주지 않는다는 거예요. 정확히는, 알려주긴 하는데 직접 들어야 해요. ...

2026년 4월 21일 · 2 분 · Young

SwiftUI @Observable에 클로저를 저장하면 EXC_BAD_ACCESS가 발생하는 이유

뭘 하려고 했냐면 iOS 음악 스트리밍 앱을 만들고 있었는데요. NavigationDestination으로 이동하는 상세 화면마다 ViewModel을 두고, API 호출 로직을 클로저로 주입하는 구조를 쓰고 있었어요. 대충 이런 식이었거든요: @Observable final class PlaylistDetailVM { var songs: [Song] = [] var isLoading = false // API 클라이언트의 메서드를 클로저로 주입 private let fetchSongs: (String) async throws -> [Song] private let addToPlaylist: (String, [String]) async throws -> Void init( fetchSongs: @escaping (String) async throws -> [Song], addToPlaylist: @escaping (String, [String]) async throws -> Void ) { self.fetchSongs = fetchSongs self.addToPlaylist = addToPlaylist } } NavigationDestination에서 @State로 VM을 생성하고요: ...

2026년 4월 21일 · 3 분 · Young

SwiftUI 이미지 깜빡임 버그 3개를 하나씩 벗겨낸 과정

문제 상황 음악 스트리밍 앱을 만들고 있었는데요. 앨범 아트워크가 계속 깜빡이는 거예요. 곡이 바뀔 때만이 아니라 같은 곡을 재생하고 있는데도 아트워크가 순간적으로 사라졌다 나타나고요. 특히 풀 플레이어의 blur 배경이 심했어요. “이미지 로딩이 느린가?” 싶어서 캐시를 넣었는데 여전히 깜빡이더라고요. 원인을 파고들었더니 버그가 3개 겹쳐 있었어요. 버그 1: NSCache 조회 순서가 반대 커스텀 CachedAsyncImage를 만들어서 NSCache에 이미지를 저장하고 있었는데요. 문제는 캐시 조회 순서였어요. ...

2026년 4월 21일 · 3 분 · Young