증상 → 빠른 조치: Xcode 27.2에서 Mac Catalyst만 빌드에 실패하고 오류가 iOS 27.1 전용 API를 가리킨다면, 플랫폼 조건부 컴파일로 해당 코드를 분리한 뒤 iOS와 Catalyst를 각각 다시 빌드하세요.
이 판단은 Apple이 Xcode 27.2 Beta 2 릴리스 노트에 기록한 문제 유형에 해당할 때만 적용합니다. 모든 Catalyst 오류의 원인이 같다고 단정하지 마세요. Apple의 Xcode 27.2 Beta 2 릴리스 노트
이 글은 iOS와 Mac Catalyst에서 코드를 함께 유지하는 개발자와, 각 빌드 대상을 관리하는 Xcode CI 엔지니어를 위한 점검 절차입니다.
원격 Mac에서 같은 오류를 재현하고 원인을 분리해야 하는 DevOps 엔지니어도 대상입니다.
마지막 확인: 2026년 10월 9일. Apple의 Xcode 27.2 릴리스 노트와 플랫폼 조건 컴파일 문서를 기준으로 확인했습니다.
SECTION 01Xcode 27.2 Mac Catalyst 빌드 실패는 알려진 문제일까요?
Apple은 Xcode 27.2 Beta 2의 알려진 문제로, iOS 27.1 전용 API를 사용하는 Mac Catalyst 빌드 오류를 기록하고 Swift와 Objective-C의 조건부 컴파일 우회 방법을 안내합니다. 이 내용은 해당 베타 상태에 대한 설명이지, 이후 Xcode 버전에도 문제가 남아 있다는 뜻은 아닙니다. 릴리스 노트에서 문제와 우회 방법 확인
오류 메시지에 undeclared identifier, not found, cannot find가 보이면 이를 단서로 삼되, 문구만으로 알려진 문제라고 판단하지 마세요. 심볼이 실제로 iOS 27.1 전용인지, Mac Catalyst 대상에서 쓸 수 있는지 확인해야 합니다. iOS 27.1 릴리스 노트와 Mac Catalyst 앱 문서를 함께 대조하면 API의 적용 범위를 확인하는 데 도움이 됩니다.
iOS 빌드는 통과하고 Mac Catalyst만 실패하면 플랫폼 API 문제인가요?
가능성은 있지만, 단일 증상만으로 확정할 수는 없습니다. 같은 커밋에서 iOS 대상은 성공하고 Catalyst 대상만 실패하는지 먼저 비교하세요. 그다음 오류 심볼의 플랫폼 가용성을 확인하고, 의존성 버전이나 빌드 설정 차이도 분리해야 합니다.
| 관찰된 결과 | 우선 확인할 항목 | 다음 조치 |
|---|---|---|
| iOS와 Catalyst에서 같은 심볼 오류가 발생함 | 소스 코드 오류, API 이름, 의존성 누락 | 오류가 발생한 모듈과 해당 심볼의 선언을 확인합니다 |
| iOS는 통과하고 Catalyst만 iOS API 관련 오류로 실패함 | API의 플랫폼 경계와 조건부 컴파일 | Catalyst에서 해당 코드가 컴파일되지 않도록 분리합니다 |
| 로컬에서는 통과하고 CI에서만 실패함 | Xcode, SDK, 빌드 설정, 체크아웃된 커밋 | 두 환경의 빌드 로그와 설정 차이를 비교합니다 |
SECTION 02플랫폼 경계와 빌드 환경을 분리해 확인하세요
Mac Catalyst는 iPad 앱을 Mac에서 실행할 수 있도록 하는 대상이지만, 모든 iOS API가 Catalyst에서도 같은 방식으로 사용된다고 가정하면 안 됩니다. Apple의 Mac Catalyst 문서는 Mac 대상 지원 여부를 확인할 때 참고할 자료입니다.
예를 들어 오류가 특정 API를 사용하는 공유 코드에서만 발생한다면, 먼저 그 코드가 앱 대상에 있는지, 공유 모듈에 있는지, 외부 패키지에 포함되어 있는지 찾으세요. 외부 패키지 코드라면 프로젝트의 빌드 설정만 바꿔서 해결할 수 없는 경우가 있습니다. 설정 차이를 의심한다면 Xcode 빌드 설정 참고 자료와 실제 빌드 로그를 함께 비교하세요.
다음 조건으로 원인과 대응을 고르면 됩니다.
- 오류가 iOS 27.1 전용 API와 연결되고 Catalyst 대상에서만 발생하면, 해당 호출을 플랫폼 조건부 컴파일로 분리하세요.
- 두 대상에서 모두 같은 선언 오류가 나면, 조건부 컴파일부터 추가하지 말고 모듈 연결, 선언 위치, 패키지 설치 상태를 확인하세요.
- 로컬과 CI에서 결과가 다르면, 공통 커밋을 기준으로 Xcode 버전과 SDK, 대상 설정, 의존성 해결 결과를 비교하세요.
- 원인이 외부 의존성에 있고 코드를 수정할 수 없다면, 버전 기록을 남긴 뒤 호환 버전으로 업그레이드하거나 대체 여부를 검토하세요. 해결 전까지 배포 대상에 포함할지는 팀의 출시 기준으로 결정하세요.
SECTION 03조건부 컴파일은 대상에 맞게 적용하세요
Mac Catalyst에서 iOS 전용 코드를 어떻게 분리하나요?
Swift에서는 targetEnvironment(macCatalyst)를, Objective-C에서는 TARGET_OS_MACCATALYST를 조건으로 사용해 대상별 컴파일 범위를 나눕니다. Apple의 Swift 조건부 컴파일 설명에서 문법을 확인하고, 실제 API의 지원 대상에 맞춰 조건을 정하세요.
Swift 코드 예시는 다음과 같습니다.
#if !targetEnvironment(macCatalyst)
// iOS에서만 사용하는 API 호출
#endif
Objective-C에서는 다음과 같이 분기할 수 있습니다.
#if !TARGET_OS_MACCATALYST
// iOS 대상에서만 컴파일할 코드
#endif
이 조건이 올바른지는 해당 API가 지원되는 플랫폼에 달려 있습니다. Catalyst에서만 제외하면 되는 코드인지, 그 밖의 플랫폼도 함께 분리해야 하는지 API 문서와 프로젝트의 대상 설정을 먼저 확인하세요.
주의: 런타임의
if문은 이미 컴파일 단계에서 실패한 API 참조를 제거하지 못합니다. 컴파일러가 대상을 선택할 수 있도록 컴파일 조건을 사용해야 합니다.
영향을 받은 함수나 선언을 통째로 제외하는 방식은 빠르게 오류를 없앨 수 있지만, iOS 쪽 기능까지 사라지거나 공유 모듈의 인터페이스가 달라질 수 있습니다. 가능한 한 문제가 된 API 사용 지점만 분리하고, 호출하는 코드와 테스트가 각 대상에서 의도대로 유지되는지 확인하세요.
SECTION 04수정 후에는 두 대상을 같은 기준으로 검증하세요
한 대상의 성공만으로 수정 완료를 선언하지 마세요. 같은 커밋에서 대상별 결과를 남기고, 프로젝트가 테스트나 아카이브를 요구한다면 해당 결과도 각각 확인해야 합니다. 아래 순서로 점검하면 재현 가능한 기록을 만들 수 있습니다.
- 실패 로그에서 실제로 컴파일되지 않는 심볼과 파일, 모듈을 확인합니다. 오류가 난 대상과 SDK도 함께 기록합니다.
- 같은 커밋을 선택해 iOS와 Mac Catalyst 빌드를 따로 실행합니다. 대상마다 사용된 Xcode 버전, SDK, 빌드 설정을 로그에서 확인합니다.
- API의 플랫폼 지원 범위를 확인한 뒤, 필요한 코드에만 Swift 또는 Objective-C 조건부 컴파일을 적용합니다.
- 의존성에서 발생한 오류라면 패키지 이름과 버전, 문제가 생기는 빌드 대상을 기록합니다. 수정 가능한 앱 코드와 수정할 수 없는 의존성 문제를 구분합니다.
- 두 대상을 다시 빌드하고, 프로젝트에서 요구하는 테스트와 아카이브도 대상별로 확인합니다. 배포 검수가 포함된다면 Apple의 앱 배포 및 아카이브 안내와 필요한 배포 경로에 맞는 문서를 참고하세요.
- CI에서도 같은 커밋과 대상 설정으로 재검증합니다. 로컬 결과만 남기지 말고 실패 로그, Xcode 버전, SDK, 대상, 테스트 결과를 한데 보관합니다.
조건부 컴파일을 넣었는데 CI에서 무엇을 다시 확인해야 하나요?
iOS와 Catalyst가 각각 컴파일되는지 확인하고, 해당 코드 경로를 사용하는 테스트와 필요한 배포 산출물이 유지되는지 살펴보세요. 등록된 기기용 배포가 필요한 프로젝트라면 Apple의 등록 기기 배포 안내를 확인하세요. CI에서만 실패하는 경우에는 수정 코드보다 먼저 실행 노드의 도구 체인과 대상별 설정 차이를 비교하는 편이 효율적입니다.
Xcode CI 실행 노드를 바꾸거나 원격 환경을 새로 도입하기 전에, 동일한 커밋을 실행 환경별로 비교할 수 있는 기록부터 마련하세요. 어떤 노드에서 재현되는지, 도구 체인과 SDK가 같은지 알 수 없다면 노드 교체만으로 원인이 해결됐다고 판단할 근거가 없습니다.
SECTION 05임시 우회는 공식 수정 여부와 프로젝트 검증으로 관리하세요
조건부 컴파일은 Beta 2 릴리스 노트에 명시된 문제 유형에 대한 우회입니다. 새 Beta, RC 또는 정식 버전으로 도구 체인을 바꿀 때는 해당 버전의 공식 릴리스 노트를 다시 확인하세요. 이전 버전에서 쓰던 분기를 바로 지우지 말고, 프로젝트의 실제 iOS 및 Catalyst 빌드 결과로 제거 여부를 판단해야 합니다.
현재 빌드 환경에서 원인을 좁히기 어렵다면, 우선 로컬 Mac이나 기존 CI에서 같은 커밋을 실행해 차이를 남기세요. 로컬 장비는 직접 제어하기 쉽지만 항상 실행 가능한 노드로 운영하면 유지 관리 부담이 생길 수 있고, 기존 CI는 익숙하더라도 실행 환경 차이를 추적하기 어려울 수 있습니다. 원격 Mac은 별도 실행 환경을 확보하는 선택지지만, 장기적으로 지속되는 무거운 작업이나 물리 인터페이스가 필요한 업무라면 자체 장비가 더 적합할 수 있습니다.
임시 검증 환경이 필요한 팀은 MACNOX 요금 및 이용 조건을 확인한 뒤, 실제 빌드 빈도와 보안 요건을 기준으로 검토할 수 있습니다. 로컬과 CI 사이에서 재현이 어려운 Catalyst 오류를 분리해야 한다면 MACNOX의 한국 이용 안내를 살펴보고, 필요한 기간에만 독립된 Mac 실행 환경을 사용하는 방안도 비교해 보세요.