# 진재명의 블로그 > 만들면서 알게 된 것들을 적어 둡니다. iOS와 소프트웨어, 그리고 덜어내는 일에 대한 기술 노트와 짧은 생각. 부산에서. 이 파일은 에이전트와 LLM이 이 블로그의 핵심 글을 빠르게 파악하도록 만든 색인입니다. 각 글 링크는 광고와 페이지 크롬을 제외한 Markdown 버전이며, Canonical 항목은 사람이 읽는 HTML 원문을 가리킵니다. ## 글 - [READY_FOR_REVIEW는 «제출됨»이 아니다: App Store Connect 제출을 멱등하게 만들기](https://blog.jaemyeong.com/posts/app-store-connect-idempotent-submission.md): 2026.08.18 · 기술 · #iOS, #CI-CD, #fastlane, #Automation, #App Store Connect - 응답이 유실되면 재실행이 중복 제출로 거부되어, 복구용 재시도가 오히려 확실한 실패가 됐습니다. 멱등 가드를 붙였더니 이번엔 그 가드가 세 가지 방향으로 배신했습니다. - [UMP가 ATT를 직접 부른다: 프레임워크 바이너리로 확인한 순서 계약](https://blog.jaemyeong.com/posts/att-ump-ordering-ios-consent.md): 2026.08.18 · 기술 · #iOS, #Swift, #Advertising, #Privacy, #ATT - AdMob IDFA 설명 메시지를 게시하려다 막혔습니다. 어느 쪽이 requestTrackingAuthorization을 부르는지 공식 문서에 없어서 UMP 프레임워크 바이너리를 읽었고, 거기서 앱과 SDK가 일회성 프롬프트를 두고 경합한다는 걸 확인했습니다. - [경고 주석은 있는데 대조는 없었다: ITSAppUsesNonExemptEncryption 두 원천 검증](https://blog.jaemyeong.com/posts/export-compliance-two-source-validation.md): 2026.08.18 · 기술 · #iOS, #CI-CD, #App Store Connect, #Automation, #Testing - 수출 규정 선언은 Info.plist와 제출 선언 파일 두 곳에 있습니다. 어긋나면 자동 제출이 멈추는데, 「한쪽만 고치지 말 것」이라는 경고 주석만 있고 실제로 대조하는 코드는 없었습니다. - [@Suite(.serialized)로는 못 막는다: Swift Testing 병렬 실행과 전역 NotificationCenter](https://blog.jaemyeong.com/posts/parallel-test-global-notification-isolation.md): 2026.08.18 · 기술 · #iOS, #Swift, #Testing, #CI-CD, #Troubleshooting - CI에서만 죽는 테스트 하나를 쫓다 45분 hang의 원인을 두 번 진단했습니다. 첫 진단은 hang만 고쳤고, 진짜 원인은 전역 NotificationCenter를 구독하는 뷰와 병렬 실행이 만든 격리 결함이었습니다. - [이미 만료된 Task.sleep은 throw하지 않는다: 버전당 1회 리뷰 요청 지키기](https://blog.jaemyeong.com/posts/task-sleep-cancellation-review-prompt-gate.md): 2026.08.18 · 기술 · #iOS, #Swift, #StoreKit, #Concurrency, #Android - AppStore.requestReview(in:)는 실패를 알려주지 않는데 게이트는 버전당 1회입니다. 같은 설계를 iOS와 Android에 옮겼더니 Swift Concurrency와 Kotlin의 취소 의미론 차이로 iOS에만 결함이 남았습니다. - [Apple Pencil 손글씨 숫자 입력: PencilKit·Core ML reject 설계](https://blog.jaemyeong.com/posts/apple-pencil-handwriting-digit-input-pipeline.md): 2026.08.07 · 기술 · #iOS, #Swift, #PencilKit, #Core ML, #Apple Pencil - PencilKit stroke를 스도쿠 숫자 입력으로 바꿀 때 필요한 tap·ink 세션 분류, 28×28 전처리, confidence reject, 비동기 추론 계약을 DailySudoku 구현으로 살펴봅니다. - [픽셀보다 계약: UIKit·Jetpack Compose 스도쿠 보드 접근성](https://blog.jaemyeong.com/posts/adaptive-accessible-sudoku-board.md): 2026.08.06 · 기술 · #Accessibility, #UIKit, #Jetpack Compose, #iOS, #Android - 하나의 9×9 커스텀 보드를 VoiceOver와 TalkBack이 탐색할 수 있는 81개 셀로 바꾸고, 위치·값·선택·오류·입력 동작을 두 플랫폼에 매핑하는 기준을 정리합니다. - [iOS·Android·Web 광고 노출: loaded·rendered·impression 구분법](https://blog.jaemyeong.com/posts/cross-platform-ad-impression-event-taxonomy.md): 2026.08.06 · 기술 · #iOS, #Android, #Web, #Advertising, #Analytics - 광고 SDK의 load·impression·paid callback과 Web 가시성 신호를 분리해, 자동 수집과 수동 로깅이 중복되지 않는 이벤트 계약을 정리합니다. - [Game Center·Play Games 리더보드: 날짜 경계·제출 신뢰성](https://blog.jaemyeong.com/posts/daily-leaderboard-date-boundary-submission-reliability.md): 2026.08.06 · 기술 · #iOS, #Android, #GameKit, #Google Play Games, #Testing - 퍼즐 날짜, 점수 제출 시각, 플랫폼 표시 구간을 분리하고 best-effort 보류와 durable outbox 사이에서 리더보드 전달 보장을 선택하는 방법을 정리합니다. - [같은 날, 같은 퍼즐: generatorVersion이 있는 PuzzleIdentity 설계](https://blog.jaemyeong.com/posts/daily-puzzle-identity-generator-version.md): 2026.08.06 · 기술 · #Rust, #Testing, #iOS, #Android, #WebAssembly - 같은 seed를 재현하는 것과 같은 퍼즐을 영구히 식별하는 것은 다르다. DailySudoku의 날짜·시간대·난이도·생성기 흐름을 바탕으로 generatorVersion, 마이그레이션, 롤백 계약을 정리합니다. - [위치 권한 없이 광고를 지역화하기: GeoIP와 Provider Chain 설계](https://blog.jaemyeong.com/posts/geoip-ad-routing-without-location-permission.md): 2026.08.06 · 기술 · #iOS, #Android, #Advertising, #Privacy, #GeoIP - OS 위치 권한 없이 동의 상태와 GeoIP 힌트로 광고 Provider Chain을 구성하고, 실패를 안전하게 흡수하는 방법을 정리합니다. - [일회성 광고 제거 IAP: StoreKit 2·Play Billing에서 구매와 권한 분리하기](https://blog.jaemyeong.com/posts/one-time-remove-ads-entitlement-storekit-play-billing.md): 2026.08.06 · 기술 · #iOS, #Android, #StoreKit, #Google Play Billing, #In-App Purchase - 결제 완료 콜백을 영구 권한으로 착각하지 않고, 앱 시작·다른 기기·pending·환불 뒤에도 광고 제거 상태를 다시 맞추는 StoreKit 2와 Play Billing 계약을 정리합니다. - [검증 스크립트가 성공을 거짓말할 때: Negative Control과 Mutation으로 자기검증하기](https://blog.jaemyeong.com/posts/verification-script-negative-control.md): 2026.08.06 · 기술 · #Testing, #CI-CD, #Automation, #Troubleshooting - 검증 스크립트가 실제 결함을 탐지하는지 Negative Control과 입력 Mutation으로 확인하고, baseline과 실패 계약을 CI에 고정하는 방법을 정리합니다. - [재시도 Cron은 자기 죽음을 알릴 수 없다: Watch the Watcher 설계](https://blog.jaemyeong.com/posts/watch-the-watcher-retry-cron-reconciliation.md): 2026.08.06 · 기술 · #CI-CD, #Automation, #Observability, #Reliability, #Cron - 기록된 job ID와 live scheduler 상태를 대조하고, 작업의 존재·실행·성공·업무 진척을 분리해 사라진 재시도 작업을 찾는 최소 운영 계약을 정리합니다. - [Rust 공통 모듈을 크로스플랫폼에서 공유하기 - 7편. 테스트와 CI로 같은 결과 보장하기](https://blog.jaemyeong.com/posts/rust-shared-core-07-testing-ci.md): 2026.07.26 · 기술 · #Rust, #CI-CD, #Testing, #UniFFI, #FFI - Rust 공통 모듈이 iOS·Android·Web에서 같은 결과를 내도록 cargo test, golden fixture, 플랫폼별 CI job 분리, release checklist를 어떻게 나눌지 정리합니다. - [Rust 공통 모듈을 크로스플랫폼에서 공유하기 - 6편. WebAssembly로 Web에 배포하기](https://blog.jaemyeong.com/posts/rust-shared-core-06-web-wasm.md): 2026.07.24 · 기술 · #Rust, #WebAssembly, #wasm-bindgen, #wasm-pack, #TypeScript - Rust 공통 모듈을 WebAssembly로 빌드해 Web 앱의 도메인 엔진으로 쓰는 구조를 wasm-bindgen, wasm-pack, browser 초기화 경계, FFI 계약, fixture 공유 기준으로 정리합니다. - [Rust 공통 모듈을 크로스플랫폼에서 공유하기 - 5편. Android 네이티브 라이브러리 패키징](https://blog.jaemyeong.com/posts/rust-shared-core-05-android-native-packaging.md): 2026.07.05 · 기술 · #Rust, #Android, #Kotlin, #Gradle, #NDK - Rust 공통 모듈을 Android 앱에 넣을 때 ABI별 .so, Gradle task, UniFFI adapter, 16 KB page size 검증을 release artifact 기준으로 정리합니다. - [Rust 공통 모듈을 크로스플랫폼에서 공유하기 - 4편. Apple 플랫폼과 XCFramework](https://blog.jaemyeong.com/posts/rust-shared-core-04-apple-xcframework.md): 2026.07.01 · 기술 · #Rust, #iOS, #Xcode, #SwiftPM, #FFI - Rust 공통 모듈을 iOS 앱에서 쓰기 위해 static library, XCFramework, Swift Package, UniFFI binding을 같은 release unit으로 묶고 Xcode와 CI에서 재현하는 기준을 정리합니다. - [automationmodetool, Xcode UI 테스트의 Automation Mode 암호 프롬프트 정리](https://blog.jaemyeong.com/posts/xcode-ui-automation-automationmodetool.md): 2026.07.01 · 기술 · #macOS, #Xcode, #XCTest, #CI-CD, #Automation - macOS에서 Xcode UI 테스트가 Automation Mode 암호 프롬프트에 막힐 때 automationmodetool이 정확히 무엇을 해결하는지 정리한다. TCC/PPPC 권한과 구분해 CI 러너 부트스트랩 위치까지 다룬다. - [Rust 공통 모듈을 크로스플랫폼에서 공유하기 - 3편. UniFFI로 iOS와 Android 연결하기](https://blog.jaemyeong.com/posts/rust-shared-core-03-uniffi-mobile.md): 2026.06.30 · 기술 · #Rust, #iOS, #Android, #UniFFI, #FFI - Rust 공통 모듈을 iOS와 Android에서 함께 쓰기 위해 UniFFI 바인딩을 설계하고, generated binding을 adapter 뒤에 숨기는 구조와 모바일 런타임 고려사항을 정리합니다. - [macOS 디버깅 권한 오류와 DevToolsSecurity -enable 작동 방식](https://blog.jaemyeong.com/posts/macos-devtoolssecurity-enable-developer-mode.md): 2026.06.26 · 기술 · #macOS, #Xcode, #DeveloperMode, #Debugging, #CI-CD - macOS에서 디버깅 도구를 사용하거나 CI/CD 러너를 빌드할 때 마주치는 디버깅 권한 팝업을 차단하고, DevToolsSecurity가 내부 인증 데이터베이스를 어떻게 조작하는지 상세히 분석합니다. - [Mac에서 Windows로 보낸 한글 파일명이 깨지는 이유: 자소 분리(NFD) 현상과 convmv 해결책](https://blog.jaemyeong.com/posts/macos-hangul-jaso-nfd-nfc.md): 2026.06.26 · 기술 · #macOS, #Unicode, #Troubleshooting, #Git - macOS에서 한글 파일명이 자소 분리(NFD)되어 Windows에서 깨지는 원인과 convmv를 사용한 해결 방법을 정리합니다. - [Rust 공통 모듈을 크로스플랫폼에서 공유하기 - 2편. FFI 경계와 API 설계](https://blog.jaemyeong.com/posts/rust-shared-core-02-ffi-api-design.md): 2026.06.26 · 기술 · #Rust, #iOS, #Android, #WebAssembly, #FFI - Rust 공통 모듈을 크로스플랫폼에서 안전하고 효율적으로 호출하기 위해 FFI 경계를 잡고 API를 설계하는 구체적인 실무 전략을 정리합니다. - [Rust 공통 모듈을 크로스플랫폼에서 공유하기 - 1편. 어디까지 Rust로 묶을 것인가](https://blog.jaemyeong.com/posts/rust-shared-core-01-architecture-boundary.md): 2026.06.24 · 기술 · #Rust, #iOS, #Android, #WebAssembly - iOS·Android·Web에서 Rust 공통 모듈을 공유할 때 도메인 엔진의 경계를 어떻게 잡을지 정리한다. 무엇을 sudoku-core에 넣고 무엇을 플랫폼에 남길지, UniFFI·WASM 바인딩 계층과 앱 adapter 구조까지 다룬다. - [iOS 런타임 폰트 등록, CTFontManagerRegisterFontsForURL 실무 정리](https://blog.jaemyeong.com/posts/ios-runtime-font-registration.md): 2026.06.18 · 기술 · #iOS, #Swift, #CoreText, #Font - iOS에서 CTFontManagerRegisterFontsForURL로 폰트를 런타임 등록하는 방법. UIAppFonts와의 차이, PostScript name 확인, 저장 위치와 해제 시점을 정리한다. - [Swift Package Registry, Git URL 의존성 이후를 준비하는 방법](https://blog.jaemyeong.com/posts/swift-package-registry.md): 2026.06.18 · 기술 · #Swift, #SwiftPM, #Package Registry, #iOS - SwiftPM의 Git URL 의존성을 넘어 scope.package-name 식별자 기반 Package Registry로. iOS 팀이 도입 전에 봐야 할 CI 속도, 의존성 재현성, 사내 패키지 배포, 패키지 서명, Xcode 설정을 정리한다. - [WWDC26, iOS 개발자가 먼저 봐야 할 변화들](https://blog.jaemyeong.com/posts/wwdc26-ios-developer-changes.md): 2026.06.18 · 기술 · #WWDC26, #iOS, #App Intents, #Apple Intelligence - App Intents·Foundation Models·Core AI·Xcode 27까지, iOS 개발자 관점에서 먼저 봐야 할 WWDC26의 변화들. ## 색인과 피드 - [홈](https://blog.jaemyeong.com/): 최신 글 목록과 카테고리 필터 - [태그](https://blog.jaemyeong.com/tags/): 주제별 글 묶음 - [RSS](https://blog.jaemyeong.com/rss.xml): 전체 본문 RSS 피드 - [Sitemap](https://blog.jaemyeong.com/sitemap.xml): 검색엔진용 사이트맵 엔트리 - [llms-full.txt](https://blog.jaemyeong.com/llms-full.txt): 현재 공개 글 전체를 하나로 묶은 Markdown 컨텍스트 ## Optional - [GitHub](https://github.com/jaemyeong): 공개 코드와 프로젝트 활동 - [개인 홈페이지](https://jaemyeong.com/): 작성자 프로필과 다른 링크