내 앱 한국음력달력의 홈 화면 이름이 “KoreanLunarCalendarApp”으로 나오고 있었다. 프로젝트 이름이 그대로 노출된 셈이다. 표시 이름을 “한국음력달력”으로 바꾸는 건 한 줄이면 끝난다. 그런데 바꾸고 나니 Spotlight에서 “lunar”로 검색이 안 됐다. 카카오톡은 “kakaotalk”으로 쳐도 잡히는데 내 앱은 왜 검색이 안 될까. 이를 가능하게 하기 위해 이것저것 시도를 해보았다.
일단 홈 화면 이름은 왜 영어였나
Tuist로 만든 프로젝트라 Info.plist에 CFBundleDisplayName이 없었다. 이 키가 없으면 iOS는
CFBundleName, 즉 프로덕트 이름을 그대로 보여준다. 그래서 “KoreanLunarCalendarApp”이었다.
// Project.swift
infoPlist: .extendingDefault(with: [
"CFBundleDisplayName": "한국음력달력",
// ...
]),
이걸로 홈 화면은 해결됐다. 문제는 그 다음이다.
Apple 엔지니어가 알려준 방법: kMDItemKeywords
Apple 개발자 포럼에 비슷한 질문이 있었다. “데스크톱에서 Twitter를 검색하면 X가 나오는 것처럼 하려면?”
Apple DTS 엔지니어의 답(2024년 8월)은 Info.plist에 키워드를 넣으라는 것이었다. iOS는 kMDItemKeywords,
macOS는 MDItemKeywords 키를 쓴다.
이 키는 원래 macOS Spotlight의 파일 메타데이터다. PDF의 키워드나 사진의 IPTC 태그 같은 것을 담는 자리인데
앱 번들도 파일이라 같은 색인을 탄다. Apple도 자기 앱에 쓴다. macOS 캘린더 앱을 mdls로 보면 이렇다.
$ mdls -name kMDItemDisplayName -name kMDItemKeywords /System/Applications/Calendar.app
kMDItemDisplayName = "캘린더"
kMDItemKeywords = "iCal,ᄏᄅᄃ,ᄃᄅ"
“iCal”을 쳐도 캘린더가 나오는 이유다. 초성 “ㅋㄹㄷ”까지 들어 있다. 번들의 Info.plist에는 MDItemKeywords 키에
“iCal”이 영어로 들어 있고, 언어별 InfoPlist 문자열로 로컬라이즈돼서 한국어 시스템에서는 연락처가 “주소록”,
시스템 설정이 “시스템 환경설정”으로 색인된다.
iOS 18.1 실기기와 시뮬레이터에서 동작을 확인했다는 글도 있었다(스토어 배포본은 미검증이라는 단서가 붙어 있다).
그래서 시도해 보았다.
"kMDItemKeywords": "Korean Lunar Calendar,lunar calendar,lunar,음력,음력달력,한국음력달력",
안 된다. 시뮬레이터에서 안 되길래 문자열 대신 배열로도 넣어 봤다. 앱을 지웠다가 다시 깔고, 시뮬레이터를 재부팅하고, TestFlight로 iOS 26 실기기에도 올려 봤다. 전부 무반응이었다.
두 번째 힌트: CFBundleName을 별칭으로
비슷한 질문(“앱 이름을 바꿨는데 옛 이름으로도 찾히게 하려면?”)이 올라온 다른 스레드에는 다른 DTS 엔지니어의
답(2024년 11월)이 있었다. iOS는 CFBundleDisplayName을 화면에 보여주지만 CFBundleName도 색인하니, 표시 이름은
새 이름으로 두고 번들 이름에 옛 이름을 남기면 둘 다로 찾을 수 있을 거라는 답이었다. 단, 번들 이름은 .app 파일
이름과 같아야 한다는 조건이 붙어 있었다.
이건 시뮬레이터에서 묘한 결과가 나왔다. 앱을 새로 설치한 직후에는 Spotlight가 앱을 번들 이름 “KoreanLunarCalendarApp”으로 색인해서 “lunar”에 잡혔다. 카멜케이스를 단어로 쪼개서 매칭한 것 같다. 부분 문자열 매칭일 수도 있다. 그런데 재부팅하고 나면 색인이 표시 이름 “한국음력달력”으로 바뀌면서 “lunar”는 안 잡히고 “음력”만 잡혔다.


“lunar”에 UI 테스트 러너(“KoreanLunarCalendarAppUITests-Runner”)가 잡힌 건 그 번들 이름에 “Lunar”가 들어 있어서다. 번들 이름 문자열 매칭 자체는 살아 있다는 뜻이다.
시뮬레이터에서는 한 번에 한 이름만 매칭됐다. 번들 이름을 “Korean Lunar Calendar”로 바꿔 봐도(.app 파일 이름은
그대로 뒀다) 표시 이름으로 색인된 상태에서는 영어 검색이 되지 않고, 롤백했다. 실기기에서는 따로 시험하지 않았다.
알고 보니 iOS 17~18부터 키워드 계열은 버그 보고가 쌓여 있었다
여기서 다시 조사했다. “키워드”라는 이름이 붙은 API마다 iOS 17~18 이후 안 된다는 글이 포럼에 여럿 올라와 있었다.
| 방법 | 보고된 상태 | 근거 |
|---|---|---|
kMDItemKeywords |
iOS 18.1에서는 됐다는 보고. 내 iOS 26 환경(시뮬레이터, TestFlight 실기기)에서는 무반응 | Zenn 글, 직접 실측. 공개된 버그 리포트는 못 찾음 |
NSUserActivity.keywords |
iOS 18+ 미동작 | FB17023996. 이전 버전에선 됐음 |
CSSearchableItem keywords (앱 내부 콘텐츠용) |
iOS 17+ 미동작, displayName만 매칭 | FB17330079, FB17408320 “조사 중” |
CFBundleName 별칭 |
시뮬레이터에서 효과 없음 | 직접 실측 |
재미있는 건 NSUserActivity 키워드가 안 된다고 접수된 스레드에서 DTS가 대안으로 권장한 게 바로 kMDItemKeywords였다는
점이다. 그런데 내 환경에서는 그것도 안 됐다.
그럼 가능한 방법은?
두 가지가 됐다.
첫째, 언어별 표시 이름. 카카오톡은 한국어 기기에서 “카카오톡”, 영어 기기에서 “KakaoTalk”으로 보이는데 한국어 기기에서 “kakaotalk”을 쳐도 잡힌다. 물론 카카오톡은 번들 이름이나 스토어 이름 때문일 수도 있어서 이것만으로 단정할 수는 없다. 다른 근거를 찾아보면 2026년 2월 Michael Tsai 블로그 댓글에 시스템 언어가 독일어인 사용자가 “iOS에서는 ‘Ca’와 ‘Ka’ 둘 다 Kalender를 찾는다”고 쓴 댓글이 있다(Apple 기본 앱 사례). 같은 댓글에서 macOS 26은 이게 깨졌지만 iOS 26에서는 살아 있다고 했다. iOS Spotlight가 앱의 다른 언어 이름까지 대조하는 것으로 보인다.
ko.lproj와 en.lproj에 InfoPlist.strings를 하나씩 둔다.
// ko.lproj/InfoPlist.strings
"CFBundleDisplayName" = "한국음력달력";
// en.lproj/InfoPlist.strings
"CFBundleDisplayName" = "Korean Lunar Calendar";
Tuist라면 Project.swift의 resources에 "KoreanLunarCalendar/Resources/**"처럼 .lproj 경로를 추가해야 번들에
들어간다. Info.plist의 CFBundleDisplayName은 strings가 없는 언어에서 쓰이는 기본값으로 그대로 둔다.
둘째, App Shortcut. WWDC23 “Spotlight your app with App Shortcuts” 세션에 명시된 동작이다.
App Shortcut은 앱 이름으로 검색할 때뿐 아니라 바로가기의 제목 자체로도 검색된다. 그러니 shortTitle이
“Korean Lunar Calendar”인 바로가기를 하나 등록하면 “lunar”를 쳤을 때 바로가기 타일로도 잡힐 수 있다. 탭하면 앱이 열린다.
import AppIntents
struct OpenKoreanLunarCalendarIntent: AppIntent {
static let title: LocalizedStringResource = "Open Korean Lunar Calendar"
static let openAppWhenRun: Bool = true
@MainActor
func perform() async throws -> some IntentResult { .result() }
}
struct KoreanLunarCalendarShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: OpenKoreanLunarCalendarIntent(),
phrases: ["Open \(.applicationName)", "\(.applicationName) 열어줘"],
shortTitle: "Korean Lunar Calendar",
systemImageName: "calendar"
)
}
}
두 개를 같이 넣고 TestFlight로 올렸다. iOS 26 실기기에서 “lunar”를 치니 앱이 떴다. 앱 줄에 “한국음력달력”이 뜨고 그 아래 회색으로 “Korean Lunar Calendar”의 “Lunar”가 강조돼 있다. 다만 이 문자열은 영어 표시 이름, 바로가기 제목, 스토어 이름에 모두 들어 있어서 어느 경로로 매칭됐는지는 이 화면만으로 알 수 없다. 둘 중 하나만 넣은 빌드로 나눠 보지는 않았다. 바로가기 타일도 이 화면에서는 따로 보이지 않았다. 그리고 맨 위 “가장 연관성 높은 항목”에는 설정 배지가 붙은 “KoreanLunarCalendarApp”이 떴다. 옛 번들 이름이 어딘가에는 아직 색인돼 있다는 뜻인데, 정확히 어떤 항목인지는 확인하지 못했다.

2.3.0이 App Store에 출시된 뒤, 앱스토어 레코드 이름도 Spotlight에 영향을 주는지 확인해보고 싶었다. DTS 답변에 iOS가 App Store 레코드의 이름도 색인한다는 말이 있었어서다. “lunar”라는 키워드는 앱스토어 레코드에도, 앱 번들에도 포함되기 때문에 이 키워드로는 영향을 주는지 아닌지 확인이 안 된다. 그래서 앱 번들에는 없고 스토어 메타데이터(부제, 설명, 키워드)에만 있는 단어 “워치 페이스”로 검색했다. “앱” 섹션에 설치된 앱이 떴다. 스토어 레코드는 번들에 들어 있지 않으니, DTS 답변대로 스토어에서 받은 레코드가 로컬 앱 검색 결과에 반영되는 것으로 보인다. 부제, 설명, 키워드 중 어느 필드가 걸린 건지는 가르지 못했다. 스토어 이름에도 “Korean Lunar Calendar”가 들어가 있으니 이것도 영어 검색 경로가 될 것으로 기대한다.
정리

| 방법 | iOS 26 결과 | 비고 |
|---|---|---|
CFBundleDisplayName 로컬라이즈 (ko/en) + App Shortcut 제목 |
된다 (둘을 같이 넣은 빌드) | 앱 줄에 정식으로 뜸. 어느 쪽이 걸렸는지는 분리 실험을 안 해서 모름. 영어 기기에서는 영어 이름이 보임 |
kMDItemKeywords |
안 된다 (내 환경) | DTS 권장 방법. iOS 18.1 동작 보고는 있으나 iOS 26 시뮬레이터와 실기기에서 무반응 |
CFBundleName 별칭 |
시뮬레이터에서 안 된다 | 실기기에서는 옛 번들 이름 항목이 따로 뜸(원인 미확인) |
| App Store 메타데이터 | 된다 | 출시 후 실기기에서 확인. 번들에 없는 스토어 단어 “워치 페이스”로 검색하니 “앱” 섹션에 뜸. 어느 필드인지는 미분리 |
요약하면, 키워드를 심는 방식은 iOS 26에서 전부 헛수고였다. 되는 건 언어별 표시 이름과 App Shortcut 제목, 그리고 스토어 이름이다. 셋 다 “앱 이름을 하나 더 갖게 하는” 방법이라는 공통점이 있다.
이번에 배운 건 Apple 엔지니어가 답변한 내용이더라도 OS 버전에 따라 달라질 수 있다는 점이다. 앞으론 답변 날짜와 버그 리포트 번호도 잘 확인해야겠다.
PS. Claude한테 테스트 시킬 수 있는 것과 없는 것
이 글의 시뮬레이터 실험은 대부분 Claude Code가 했다. 나는 “시뮬레이터로 다시 실행해서 확인해”라고 했을 뿐이다. 검색어 세 개(“lunar”, “korean lunar”, “음력”)를 넣고, 앱을 지웠다 깔고, 재부팅하고, 그때마다 스크린샷을 찍어 보여주는 일을 Claude가 반복했다.
처음에는 cliclick으로 시뮬레이터 창을 직접 클릭하려 했다. 그런데 클릭이 뒤에 있던 VS Code 창으로 새어 들어갔다.
창 좌표 보정이 틀렸기 때문이다. 내가 다른 창에서 작업 중이라 마우스를 계속 건드리게 두면 위험했고, Claude도
그 시점에서 방법을 바꿨다.
바꾼 방법은 XCUITest로 SpringBoard를 직접 조작하는 것이다. 임시 테스트 파일 하나를 만들어 Spotlight를 열고
검색어를 치고 결과를 확인하게 했다. 홈 화면 하단 검색 알약은 spotlight-pill이라는 접근성 식별자가 붙어 있는데
같은 식별자가 두 개라서 firstMatch가 필요하다. 시뮬레이터 기본 키보드가 한글이라 영어를 치기 전에 지구본 키로
전환해야 했다. 이런 건 Claude가 실패 로그를 보고 스스로 찾아냈다.
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
XCUIDevice.shared.press(.home)
springboard.otherElements["spotlight-pill"].firstMatch.tap()
springboard.keyboards.buttons["다음 키보드"].tap() // 한글 → 영어
springboard.typeText("lunar")
let found = springboard.staticTexts["한국음력달력"].waitForExistence(timeout: 5)
지구본 키 레이블 “다음 키보드”는 시스템 언어가 한국어일 때 기준이다. 환경이 다르면 레이블도 다르다.
스크린샷은 XCUIScreen.main.screenshot().pngRepresentation을 호스트 경로에 바로 써서 Claude가 읽고 판단했다.
나는 결과 캡처만 확인하였다. 사람이 했으면 검색어 세 개를 삭제, 재설치, 재부팅 조합마다 손으로 쳤을 일이다.
다만 시뮬레이터로 안 되는 것도 있었다. 언어별 표시 이름과 App Shortcut은 시뮬레이터 색인이 설치 직후와 재부팅 후에 다르게 잡혀서 결과를 믿기 어려웠고, TestFlight로 올려 실기기에서 확인했다. App Store 레코드 색인은 시뮬레이터에 스토어 레코드가 붙을 일이 없어서 아예 시험할 수 없었고, 출시 후 스토어 부제에 포함되고 앱 번들에는 미포함인 “워치 페이스”라는 키워드로 검색하여 확인할 수 있었다.
참고
- Apple Forums: I want to add keywords to the system search App name
- Apple Forums: How to find renamed app using old name in Spotlight?
- Apple Forums: Spotlight search by keywords in NSUserActivity doesn’t work (iOS 18)
- Apple Forums: Core Spotlight keyword matching broken iOS 17/18
- Michael Tsai: Searching for Apps With Spotlight
- WWDC23: Spotlight your app with App Shortcuts
- Zenn: Spotlight検索で自分のiOSアプリが引っかかるキーワードを増やす
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.