XCFramework는 iOS, macOS, tvOS 및 watchOS용 라이브러리를 단일 패키지로 결합하는 Apple의 바이너리 형식입니다. .framework를 대체하고 시뮬레이터와 기기의 서로 다른 아키텍처로 빌드할 때 fat binary의 문제를 해결하기 위해 설계되었습니다. Apple WWDC 2019에 따르면, XCFramework는 여러 플랫폼을 지원하는 SDK 배포를 위한 필수 형식이 되었으며, 유니버설 바이너리의 구식 접근 방식을 완전히 대체했습니다.
핵심 사항
XCFramework는 Apple이 WWDC 2019에서 발표한 바이너리 라이브러리 및 프레임워크용 패키징 형식입니다. 주요 목표는 모든 대상 플랫폼 및 아키텍처에 대한 라이브러리의 컴파일된 버전을 포함하는 단일 번들을 만드는 것입니다.
XCFramework 이전에는 개발자가 lipo 유틸리티를 통해 여러 아키텍처를 결합하는 fat binary와 함께 .framework를 사용했습니다. 이 접근 방식은 문제를 일으켰습니다. 시뮬레이터용 프로젝트를 빌드할 때 fat binary에는 시뮬레이터와 기기 아키텍처가 모두 포함되어 App Store에 빌드를 제출할 때 오류가 발생했습니다. 개발자는 불필요한 아키텍처를 제거하기 위해 Run Script 단계를 작성해야 했습니다.
Apple 개발자 문서(2024)에 따르면, XCFramework는 Apple 생태계의 모든 플랫폼(iOS, iPadOS, macOS, tvOS, watchOS, visionOS 및 Catalyst 애플리케이션)을 지원합니다. 각 플랫폼은 패키지 내에서 별도의 슬라이스를 받아 아키텍처 충돌을 제거하고 SDK 배포를 간소화합니다.
XCFramework는 세 가지 주요 시나리오에서 사용됩니다: 타사 개발자에게 폐쇄형 SDK 배포, Flutter 및 React Native용 네이티브 모듈 배포, 사전 컴파일이 필요한 라이브러리 게시. 이 형식은 Apple 생태계에 게시되는 모든 새 SDK에 필수입니다.
개발자는 소스 코드를 공개할 수 없을 때, 라이브러리가 독점 알고리즘을 사용할 때, 또는 라이선스 보호가 필요할 때 XCFramework를 선택합니다. 소스 코드로 작업하는 Swift Package Manager와 달리 XCFramework는 이미 컴파일된 바이너리 파일을 제공합니다.
Fat binary 문제는 유니버설 바이너리가 단일 Mach-O 파일에 여러 아키텍처를 포함한다는 것이었습니다. 시뮬레이터용 앱을 빌드할 때 Xcode는 기기 아키텍처 arm64와 시뮬레이터 아키텍처 x86_64를 모두 포함했습니다 — App Store는 기기 아키텍처만 허용했습니다.
전통적인 해결책은 최종 빌드에서 시뮬레이터 아키텍처를 제거하기 위해 lipo를 호출하는 Run Script 단계를 추가하는 것이었습니다. 이 접근 방식은 취약했고 Xcode 업데이트나 새로운 아키텍처(예: Apple Silicon의 시뮬레이터용 arm64)가 나타날 때 깨졌습니다.
Swift.org(2023)에 따르면, Swift Package Manager 팀은 바이너리 종속성을 지원하려고 할 때 처음에 이 문제에 직면했습니다. XCFramework는 형식 수준에서 이 문제를 해결했습니다. 각 슬라이스는 대상 플랫폼과 아키텍처를 설명하는 Info.plist가 있는 별도의 폴더입니다. Xcode는 빌드 시 자동으로 필요한 슬라이스를 선택하며 후처리가 필요하지 않습니다.
XCFramework의 각 슬라이스는 하나의 플랫폼-아키텍처 조합만 포함합니다. 예를 들어, ios-arm64는 iOS 기기용 바이너리만 포함하고, ios-x86_64-simulator는 Intel Mac 시뮬레이터용만 포함합니다. Xcode는 자동으로 올바른 슬라이스를 선택하여 아키텍처 제거 스크립트의 필요성을 없애고 빌드 오류 위험을 줄입니다.
ios-arm64-x86_64-simulator 슬라이스는 Apple Silicon Mac을 지원하기 위해 도입되었습니다. 이전에는 시뮬레이터에 arm64(Apple Silicon)와 x86_64(Intel)용 별도 바이너리가 필요했습니다. XCFramework는 단일 시뮬레이터 슬라이스 내에서 fat binary를 허용합니다 — 이것이 fat binary가 정당화되는 유일한 예외입니다.
XCFramework 패키지는 .xcframework 확장자를 가진 디렉토리로, 최상위에 Info.plist와 바이너리 슬라이스가 있는 폴더를 포함합니다. 각 슬라이스에는 특정 플랫폼용 .framework 또는 .a 라이브러리가 포함됩니다.
MyLibrary.xcframework/
Info.plist
ios-arm64/
MyLibrary.framework/
Info.plist
MyLibrary
ios-x86_64-simulator/
MyLibrary.framework/
Info.plist
MyLibrary
macos-arm64-x86_64/
MyLibrary.framework/
Info.plist
MyLibrary
패키지의 Info.plist에는 AvailableLibraries 키가 포함되어 각 슬라이스의 LibraryIdentifier, LibraryPath 및 SupportedPlatform을 나열합니다. Xcode는 프로젝트에 XCFramework를 추가할 때 이 파일을 읽고 검색 경로와 Embed Frameworks 단계를 자동으로 구성합니다.
각 슬라이스는 자체 Info.plist가 있는 완전한 .framework 또는 정적 라이브러리입니다. 이를 통해 XCFramework는 혼합 유형(일부 플랫폼의 경우 정적 라이브러리, 다른 플랫폼의 경우 동적 프레임워크)을 지원할 수 있지만, 실제로는 모든 슬라이스에 하나의 유형이 사용됩니다.
XCFramework 생성은 xcodebuild -create-xcframework를 통해 수행됩니다. 이 명령은 각 플랫폼용으로 이미 빌드된 .framework 또는 .a 라이브러리를 입력으로 받아 단일 패키지로 결합합니다.
프로세스는 두 단계로 구성됩니다: 먼저 각 대상 플랫폼용 바이너리가 빌드된 다음 XCFramework로 패키징됩니다. 빌드에는 표준 Xcode destination 플래그가 사용됩니다.
# Step 1: build frameworks for each platform
xcodebuild archive -scheme MyLibrary -destination "generic/platform=iOS Simulator"
xcodebuild archive -scheme MyLibrary -destination "generic/platform=iOS"
xcodebuild archive -scheme MyLibrary -destination "generic/platform=macOS"
# Step 2: create XCFramework
xcodebuild -create-xcframework -framework ./iOS/MyLibrary.framework -framework ./iOSSim/MyLibrary.framework -framework ./macOS/MyLibrary.framework -output ./MyLibrary.xcframework
-create-xcframework 플래그는 Xcode 11에서 도입되었습니다. 이 명령은 자동으로 올바른 디렉토리 구조를 만들고 모든 플랫폼에 대한 설명이 포함된 Info.plist를 생성합니다. .framework 중 하나가 손상되었거나 잘못된 아키텍처로 빌드된 경우 xcodebuild는 검증 단계에서 오류를 출력합니다.
CI/CD의 경우 모든 플랫폼에 대한 빌드와 XCFramework 생성을 자동화하는 셸 스크립트가 사용됩니다. 일반적인 접근 방식은 매개변수화된 scheme 및 출력 경로가 있는 Makefile 또는 Fastlane lane 형태의 래퍼입니다.
# build_xcframework.sh - automation script
set -e
SCHEME="MyLibrary"
OUTPUT="./build"
xcodebuild archive -scheme "$SCHEME" -sdk iphonesimulator -archivePath "$OUTPUT/sim.xcarchive"
xcodebuild archive -scheme "$SCHEME" -sdk iphoneos -archivePath "$OUTPUT/dev.xcarchive"
xcodebuild -create-xcframework -framework "$OUTPUT/dev.xcarchive/Products/Library/Frameworks/MyLibrary.framework" -framework "$OUTPUT/sim.xcarchive/Products/Library/Frameworks/MyLibrary.framework" -output "$OUTPUT/MyLibrary.xcframework"
이러한 스크립트는 테스트 통과 후 CI 파이프라인(GitHub Actions, Bitrise, Jenkins)에서 실행됩니다. 결과 XCFramework는 보관되어 릴리스 아티팩트로 업로드되거나 pod spec을 통해 CocoaPods와 같은 종속성 관리자를 통해 게시됩니다.
XCFramework를 Xcode 프로젝트에 통합하는 데 검색 경로의 수동 구성이 필요하지 않습니다. target의 General 설정에서 .xcframework를 Frameworks, Libraries, and Embedded Content 섹션으로 끌어다 놓기만 하면 됩니다.
.framework와 달리 XCFramework는 시뮬레이터 아키텍처를 제거하기 위해 Run Script 단계를 추가할 필요가 없습니다. Xcode는 자동으로 사용 가능한 슬라이스를 결정하고 현재 빌드 체계에 필요한 것만 포함합니다. 물리적 기기의 경우 ios-arm64 슬라이스가 사용되고, 시뮬레이터의 경우 ios-arm64-x86_64-simulator 또는 ios-x86_64-simulator가 사용됩니다.
import MyLibrary
func processData() {
// XCFramework resolves the correct slice at build time
let processor = DataProcessor()
let result = processor.analyze(input: "sample")
print(result)
}
CocoaPods의 경우 vendored_frameworks 및 지원되는 플랫폼 목록이 포함된 podspec을 통해 통합이 이루어집니다. 종속성 관리자는 프로젝트에 필요한 슬라이스를 자동으로 결정합니다. 많은 상용 SDK(Firebase, Adjust, AppsFlyer)가 설치를 간소화하기 위해 XCFramework로 전환했습니다.
Swift Package Manager와 XCFramework는 경쟁 관계가 아니라 서로를 보완합니다. SPM은 소스 코드로 작업하고 프로젝트 빌드 시마다 종속성을 컴파일합니다. XCFramework는 소비자 측에서 컴파일할 필요 없이 준비된 바이너리를 제공합니다.
Swift Package Manager 5.3의 출시와 함께 Apple은 바이너리 종속성 지원을 추가했습니다 — 이제 SPM은 원격 종속성으로 XCFramework를 다운로드할 수 있습니다. Package.swift는 바이너리 아티팩트의 URL과 검증을 위한 체크섬을 지정합니다.
Swift Package Manager 문서(2024)에 따르면, 바이너리 종속성은 소스 코드를 공개하지 않는 SDK나 빌드 시간이 불균형적으로 긴 라이브러리에 권장됩니다. 오픈 소스 프로젝트의 경우 SPM을 통한 소스 코드 배포가 선호됩니다.
| 기준 | XCFramework | Swift Package Manager |
|---|---|---|
| 형식 | 바이너리 (.xcframework) | 소스 코드 |
| 코드 보호 | 완전 | 없음 |
| 빌드 시간 | 최소 (복사) | 코드 양에 따라 다름 |
| 플랫폼 유연성 | 모든 Apple 플랫폼 | Package.swift에 따라 다름 |
| 통합 | 드래그 앤 드롭 또는 SPM | Package.swift |
자주 묻는 질문
.framework는 기기 및 시뮬레이터 아키텍처가 포함된 fat binary를 가진 레거시 형식입니다. XCFramework는 각 슬라이스를 별도로 저장하여 빌드 중 아키텍처 충돌을 제거합니다. Apple은 모든 새 프로젝트와 기존 프로젝트 마이그레이션에 XCFramework를 권장합니다.
CocoaPods는 버전 1.9부터 XCFramework를 지원합니다. podspec에서 spec.vendored_frameworks와 spec.static_framework를 지정하면 됩니다. 관리자는 프로젝트 플랫폼에 사용 가능한 슬라이스를 고려하여 자동으로 종속성을 해결합니다.
Apple은 .framework에 대한 지원을 제거하지 않지만 새 SDK에는 독점적으로 XCFramework를 권장합니다. 이전 형식의 fat binary로 App Store에 앱을 제출하면 시뮬레이터 아키텍처로 인해 Invalid Bundle 오류가 발생할 수 있어 XCFramework가 실질적인 필요성이 됩니다.
Swift 5.3부터 SPM의 바이너리 종속성은 XCFramework를 사용합니다. Package.swift는 바이너리 패키지의 url과 체크섬을 지정합니다. SPM은 다운로드하고 무결성을 확인한 다음 소스 코드를 컴파일하지 않고 XCFramework를 시스템 종속성으로 연결합니다.
visionOS는 Xcode 15부터 XCFramework에서 지원됩니다. WWDC 2023에서 Apple은 이 형식이 Apple Vision Pro용으로 확장되었음을 확인했습니다. visionOS용 슬라이스는 SupportedPlatform = xros이며 arm64 아키텍처를 포함합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.