← 전체 글로

AI 사용기

iOS 홈 화면 앱 이름이 다를 때: 최종 Info.plist부터 확인하기

Xcode 27에서 생성 모드와 입력 파일을 바꿔 표시 이름을 네 번 빌드했다. 최종 앱에 OldName이 남는 조건과 NewName으로 고치는 위치를 비교한다.

2026년 10월 9일 조사·격리 빌드·작성한 글입니다.

이 글의 목적

Xcode에서 이름을 바꿨는데 설치 앱 이름이 다른 개발자가 실제 빌드에 들어간 값을 찾도록 돕는다.

핵심 내용

수동 plist 모드의 고정 표시 이름은 생성용 설정만 바꿔도 남을 수 있다. 생성 모드와 입력 파일을 확인하고 최종 앱 번들의 값을 다시 읽는다.

읽고 나서

문제가 난 앱 타깃과 구성의 빌드 설정에서 GENERATE_INFOPLIST_FILE과 INFOPLIST_FILE을 확인한다.

목차

먼저 답하면

iOS 홈 화면 앱 이름이 Xcode에서 바꾼 이름과 다르면, 빌드된 앱의 Info.plist에서 CFBundleDisplayName부터 읽는다. 이 키는 Apple이 정의한 홈 화면 표시 이름이다. 설정 화면에 원하는 이름이 보인다는 사실만으로 최종 앱에도 같은 값이 들어갔다고 판단할 수 없다.

GENERATE_INFOPLIST_FILE=NO이고 입력 plist에 OldName이 고정 문자열로 있으면, 생성용 INFOPLIST_KEY_CFBundleDisplayName=NewName만 바꾸는 것으로는 부족할 수 있다. 아래 최소 시험에서는 최종 값이 OldName이었다. 수동 모드라면 실제 입력 파일의 키를, 자동 생성 모드라면 생성용 설정을 확인한다. 어느 쪽이든 재빌드한 앱의 값을 다시 읽는 것이 성공 확인이다.

독립 예제부터 비교하려면 NameProbe.zip 받기를 풀고 터미널에서 압축을 푼 NameProbe 폴더로 이동한다. Xcode와 iOS Simulator SDK가 설치된 Mac이 필요하다. XcodeGen이나 외부 패키지 설치, Apple 계정, 시뮬레이터 부팅은 필요 없다.

xcodebuild -project NameProbe.xcodeproj -scheme NameProbe \
  -configuration Debug -sdk iphonesimulator \
  -destination 'generic/platform=iOS Simulator' \
  -derivedDataPath DerivedData CODE_SIGNING_ALLOWED=NO build

plutil -extract CFBundleDisplayName raw -o - \
  DerivedData/Build/Products/Debug-iphonesimulator/NameProbe.app/Info.plist

첫 출력은 OldName이다. 예제 폴더에서 아래처럼 입력 파일을 고친 뒤 같은 빌드와 읽기 명령을 다시 실행하면 NewName이 나온다.

plutil -replace CFBundleDisplayName -string NewName Info.plist

이 수정 명령은 받은 예제에만 그대로 적용한다. 기존 앱에서는 먼저 아래 절차로 실제 입력 파일을 찾아야 한다. 설치 앱의 데이터를 지우거나 앱을 삭제할 필요는 없다.

기존 프로젝트에서 입력과 최종 파일 찾기

Xcode의 앱 타깃, Debug/Release 구성, 빌드 대상을 문제를 본 경우와 맞춘다. 다음은 예제의 Debug·Simulator 명령이다. 실제 프로젝트에서는 NameProbe.xcodeproj와 NameProbe를 자기 프로젝트 파일·앱 스킴으로 바꾼다. workspace를 쓰는 프로젝트라면 -project ... 대신 -workspace 자신의파일.xcworkspace를 쓴다. 아래 명령은 Simulator용이므로 실기기·Archive 결과를 검사하는 명령으로 재사용하지 않는다.

xcodebuild -project NameProbe.xcodeproj -scheme NameProbe \
  -configuration Debug -sdk iphonesimulator \
  -destination 'generic/platform=iOS Simulator' \
  -derivedDataPath DerivedData -showBuildSettings

출력이 길면 같은 명령 끝에 > build-settings.txt를 붙여 저장한 뒤 파일에서 아래 키를 검색한다. 여러 타깃이 나오면 앱 타깃의 구획을 읽는다.

키 확인할 내용
GENERATE_INFOPLIST_FILE plist를 생성·병합하는지, 제공 파일을 처리하는지
INFOPLIST_FILE 제공하는 입력 파일 경로. 상대 경로라면 해당 타깃의 SRCROOT 기준으로 찾기
INFOPLIST_KEY_CFBundleDisplayName 생성용 표시 이름 설정
PRODUCT_NAME 제품 이름. 표시 이름의 고정 문자열과는 따로 확인
TARGET_BUILD_DIR + INFOPLIST_PATH 빌드된 최종 plist의 경로

이 예제는 TARGET_BUILD_DIR가 DerivedData/Build/Products/Debug-iphonesimulator에 해당하고, INFOPLIST_PATH가 NameProbe.app/Info.plist다. 두 경로를 연결한 파일에서 값을 읽었다. 자기 앱에서도 실제 출력 경로를 사용한다.

# 예제의 최종 파일. 자신의 앱에서는 위 두 설정을 연결한 경로로 바꾼다.
/usr/libexec/PlistBuddy -c 'Print :CFBundleDisplayName' \
  'DerivedData/Build/Products/Debug-iphonesimulator/NameProbe.app/Info.plist'

파일이 없으면 먼저 같은 구성으로 빌드가 성공했는지 확인한다. 키가 없다는 오류는 OldName을 읽었다는 뜻과 다르다. 해당 키가 최종 파일에 들어가지 않은 경로이므로 생성 설정·입력 파일을 다시 확인하고, CFBundleName도 따로 살펴본다.

생성 모드에 따라 고칠 값이 다르다

Apple의 plist 관리 문서는 GENERATE_INFOPLIST_FILE=YES일 때 제공 파일과 생성 설정을 병합하고, NO일 때 제공 파일을 처리한다고 구분한다. 수동 모드에서도 $(PRODUCT_NAME) 같은 빌드 변수는 치환된다. 모든 빌드 설정이 무시된다는 뜻은 아니다.

  • NO + 입력 파일 있음: 실제 INFOPLIST_FILE의 CFBundleDisplayName 값을 읽는다. OldName 같은 고정 문자열이면 그 값을 바꾼다. $(PRODUCT_NAME) 등 변수이면 참조한 변수의 해당 구성 값을 확인한다. 파일을 찾지 않고 저장소의 다른 Info.plist를 수정하지 않는다.
  • YES + 입력 파일 없음: 해당 타깃·구성의 INFOPLIST_KEY_CFBundleDisplayName을 확인한다. 설정값이 원하는 이름인지 보고 빌드한다.
  • YES + 입력 파일도 있음: 양쪽 값을 읽고 충돌을 확인한다. 아래 시험에서는 생성 설정의 이름이 최종 파일에 들어갔지만, 다른 키나 Xcode 버전의 일반 우선순위 규칙으로 확대하지 않는다. 이름을 어느 입력에서 관리할지 정하고 최종 값을 대조한다.

General의 Display Name을 바꾸는 방법 자체가 항상 잘못된 것은 아니다. 프로젝트가 어떤 입력을 쓰는지에 따라 확인해야 할 곳이 달라진다. GENERATE_INFOPLIST_FILE을 무작정 뒤집으면 다른 plist 값에도 영향을 줄 수 있으므로 이름 하나를 고치려고 생성 방식을 바꾸는 것부터 시작하지 않는다.

같은 NewName 설정을 네 번 빌드한 결과

2026년 10월 9일 macOS 26.6.2 arm64, Xcode 27.0(27A266a), iOS Simulator SDK, Debug 구성으로 새 최소 UIKit 앱을 빌드했다. 예제 프로젝트는 XcodeGen 2.46.0으로 만들었고, 다운로드에는 생성된 프로젝트를 포함했다. 제품 이름은 모두 NameProbe, 생성용 표시 이름 설정은 모두 NewName이었다. 각 시험은 별도 빌드 폴더에서 실행했고 네 빌드 모두 종료 코드 0이었다.

생성 모드 입력 파일의 표시 이름 최종 CFBundleDisplayName
NO OldName OldName
NO NewName으로 수정 NewName
YES, 입력 파일 지정 없음 파일을 사용하지 않음 NewName
YES, 입력 파일도 지정 OldName NewName

첫 행에서 CFBundleName은 NameProbe였다. 제품 이름과 표시 이름은 실제로 다른 값이었다. 두 번째 행은 첫 행의 입력 파일 표시 이름만 바꾼 수정이다. 생성 모드와 생성용 설정은 유지했는데 최종 값이 바뀌었다. 이 비교 때문에 수동 모드에서 수정할 곳을 입력 파일로 좁힐 수 있다.

다운로드의 README.md에는 자동 생성 모드 비교 명령도 있다. 이 결과는 빌드된 번들의 값을 확인한 것이다. 기존 사용자 앱을 실행했거나 설치 후 홈 화면이 바뀌는 장면을 관측한 것은 아니다.

최종 값은 맞는데 설치 이름이 다르면

Apple QA1823는 표시 이름을 현지화하는 앱에서 각 언어의 InfoPlist.strings도 함께 관리하라고 안내한다. 기본 plist만 보고 끝내지 말고 앱에 포함된 언어별 파일의 CFBundleDisplayName도 확인한다. 이 문서는 2015년 자료이므로 당시 UI 그림을 현재 Xcode의 메뉴 위치 안내로 쓰지는 않는다.

그다음 실제 설치한 앱이 방금 검사한 빌드인지, 문제가 난 구성·타깃과 같은지 확인하고 원래 이름 불일치를 본 동작을 다시 확인한다. Simulator Debug의 값이 맞았다는 사실만으로 Release·Archive·실기기 값까지 맞다고 결론 내리지 않는다. 스토어 이름이나 번들 식별자를 바꾸는 것도 이 글의 수정 대상이 아니다.

이 시험은 현지화된 런타임 이름, 실제 홈 화면, 실기기 설치, 캐시 해소, 서명, Archive와 스토어 제출을 검증하지 않았다. 최종 번들 값이 이미 맞다면 입력 파일을 계속 바꾸기보다 그 이후의 설치·언어·구성 경로를 좁힌다. 앱 삭제나 재부팅이 해결책이라고 이 결과만으로 판단할 근거는 없다.

AI가 공식 자료 조사, 새 최소 예제 작성·빌드, 초안 작성과 별도 자동 검토를 수행했습니다. 실행 로그와 원문을 대조하며 실제 사용자 앱이나 홈 화면을 시험한 경험으로 서술하지 않습니다.