XCFramework est un format binaire Apple qui combine des bibliothèques pour iOS, macOS, tvOS et watchOS dans un seul paquet. Il a été conçu pour remplacer .framework et éliminer les problèmes de fat binaries lors de la compilation pour différentes architectures de simulateur et d'appareil. Selon Apple WWDC 2019, XCFramework est devenu le format obligatoire pour la distribution de SDK prenant en charge plusieurs plateformes, et a complètement remplacé l'approche obsolète des binaires universels.
Points clés
XCFramework est un format d'empaquetage pour bibliothèques et frameworks binaires présenté par Apple à la WWDC 2019. L'objectif principal est de créer un bundle unique contenant des versions compilées d'une bibliothèque pour toutes les plateformes et architectures cibles.
Avant XCFramework, les développeurs utilisaient .framework avec des fat binaries combinant plusieurs architectures via l'utilitaire lipo. Cette approche posait problème : lors de la compilation d'un projet pour le simulateur, le fat binary contenait à la fois l'architecture du simulateur et celle de l'appareil, ce qui entraînait des erreurs lors de l'envoi du build vers l'App Store. Les développeurs devaient écrire des phases Run Script pour supprimer les architectures inutiles.
Selon la Documentation Développeur Apple (2024), XCFramework prend en charge toutes les plateformes de l'écosystème Apple : iOS, iPadOS, macOS, tvOS, watchOS, visionOS et les applications Catalyst. Chaque plateforme reçoit un slice séparé à l'intérieur du paquet, éliminant les conflits d'architecture et simplifiant la distribution des SDK.
XCFramework est utilisé dans trois scénarios principaux : distribution de SDK fermés à des développeurs tiers, distribution de modules natifs pour Flutter et React Native, et publication de bibliothèques nécessitant une précompilation. Le format est obligatoire pour tous les nouveaux SDK publiés dans l'écosystème Apple.
Les développeurs choisissent XCFramework lorsque le code source ne peut pas être divulgué, lorsque la bibliothèque utilise des algorithmes propriétaires ou lorsqu'une protection de licence est requise. Contrairement à Swift Package Manager, qui fonctionne avec du code source, XCFramework livre des fichiers binaires déjà compilés.
Le problème du fat binary était qu'un binaire universel contenait plusieurs architectures dans un seul fichier Mach-O. Lors de la compilation d'une application pour le simulateur, Xcode incluait à la fois l'architecture arm64 de l'appareil et l'architecture x86_64 du simulateur — l'App Store n'acceptait que l'architecture de l'appareil.
La solution traditionnelle consistait à ajouter une phase Run Script appelant lipo pour supprimer les architectures du simulateur du build final. Cette approche était fragile et se brisait avec les mises à jour de Xcode ou l'apparition de nouvelles architectures (par exemple, arm64 pour le simulateur sur Apple Silicon).
Selon Swift.org (2023), l'équipe de Swift Package Manager a initialement rencontré ce problème en essayant de prendre en charge les dépendances binaires. XCFramework l'a résolu au niveau du format : chaque slice est un dossier séparé avec un Info.plist décrivant la plateforme et l'architecture cibles. Xcode sélectionne automatiquement le slice nécessaire lors de la compilation, sans nécessiter de post-traitement.
Chaque slice dans XCFramework contient une seule combinaison plateforme-architecture. Par exemple, ios-arm64 contient le binaire uniquement pour les appareils iOS, et ios-x86_64-simulator uniquement pour le simulateur Intel Mac. Xcode sélectionne automatiquement le slice correct, éliminant le besoin de scripts de suppression d'architectures et réduisant le risque d'erreurs de compilation.
Le slice ios-arm64-x86_64-simulator a été introduit pour prendre en charge les Mac Apple Silicon. Auparavant, le simulateur nécessitait un binaire séparé pour arm64 (Apple Silicon) et x86_64 (Intel). XCFramework autorise un fat binary à l'intérieur d'un seul slice de simulateur — c'est la seule exception où le fat binary est justifié.
Un paquet XCFramework est un répertoire avec l'extension .xcframework, contenant un Info.plist au niveau supérieur et des dossiers avec des slices binaires. Chaque slice inclut une bibliothèque .framework ou .a pour une plateforme spécifique.
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
L'Info.plist du paquet contient la clé AvailableLibraries, listant LibraryIdentifier, LibraryPath et SupportedPlatform pour chaque slice. Xcode lit ce fichier lors de l'ajout d'un XCFramework au projet et configure automatiquement les chemins de recherche et la phase Embed Frameworks.
Chaque slice est un .framework complet ou une bibliothèque statique avec son propre Info.plist. Cela permet à XCFramework de prendre en charge des types mixtes : bibliothèques statiques pour certaines plateformes et frameworks dynamiques pour d'autres, bien qu'en pratique un type soit utilisé pour tous les slices.
La création d'un XCFramework s'effectue via xcodebuild -create-xcframework. La commande prend des bibliothèques .framework ou .a déjà compilées pour chaque plateforme et les combine en un seul paquet.
Le processus comprend deux étapes : d'abord, les binaires sont compilés pour chaque plateforme cible, puis ils sont empaquetés dans un XCFramework. Pour la compilation, on utilise les flags de destination standard de Xcode.
# 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
Le flag -create-xcframework a été introduit dans Xcode 11. La commande crée automatiquement la structure de répertoires correcte et génère un Info.plist avec la description de toutes les plateformes. Si l'un des .framework est endommagé ou compilé avec la mauvaise architecture, xcodebuild émet une erreur à l'étape de validation.
Pour le CI/CD, on utilise un script shell qui automatise la compilation pour toutes les plateformes et la création du XCFramework. Une approche populaire est un wrapper sous forme de Makefile ou de Fastlane lane avec paramétrisation du scheme et du chemin de sortie.
# 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"
Ce script s'exécute dans un pipeline CI (GitHub Actions, Bitrise, Jenkins) après la réussite des tests. Le XCFramework résultant est archivé et téléchargé comme artefact de version ou publié via un gestionnaire de dépendances comme CocoaPods à l'aide de pod spec.
Intégrer un XCFramework dans un projet Xcode ne nécessite pas de configuration manuelle des chemins de recherche. Il suffit de glisser-déposer le .xcframework dans la section Frameworks, Libraries, and Embedded Content dans les paramètres Généraux du target.
Contrairement à .framework, XCFramework ne nécessite pas d'ajouter une phase Run Script pour supprimer les architectures du simulateur. Xcode détermine automatiquement les slices disponibles et n'inclut que ceux nécessaires au schéma de compilation actuel. Pour un appareil physique, on utilise le slice ios-arm64 ; pour le simulateur — ios-arm64-x86_64-simulator ou 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)
}
Pour CocoaPods, l'intégration se fait via un podspec avec vendored_frameworks et une liste des plateformes supportées. Le gestionnaire de dépendances détermine automatiquement les slices nécessaires au projet. De nombreux SDK commerciaux — Firebase, Adjust, AppsFlyer — sont passés à XCFramework pour simplifier l'installation.
Swift Package Manager et XCFramework ne sont pas concurrents mais complémentaires. SPM fonctionne avec du code source et compile les dépendances à chaque compilation du projet. XCFramework fournit des binaires prêts sans nécessiter de compilation côté consommateur.
Avec la sortie de Swift Package Manager 5.3, Apple a ajouté la prise en charge des dépendances binaires — désormais SPM peut télécharger un XCFramework comme dépendance distante. Package.swift spécifie l'URL de l'artefact binaire et sa somme de contrôle pour vérification.
Selon la documentation de Swift Package Manager (2024), les dépendances binaires sont recommandées pour les SDK qui ne divulguent pas le code source, ou pour les bibliothèques dont le temps de compilation est disproportionné. Pour les projets open source, la distribution du code source via SPM est préférée.
| Critère | XCFramework | Swift Package Manager |
|---|---|---|
| Format | Binaire (.xcframework) | Code source |
| Protection du code | Totale | Aucune |
| Temps de compilation | Minimal (copie) | Dépend du volume de code |
| Flexibilité des plateformes | Toutes les plateformes Apple | Dépend de Package.swift |
| Intégration | Glisser-déposer ou SPM | Package.swift |
Foire aux questions
.framework est un format hérité contenant un fat binary avec les architectures de l'appareil et du simulateur. XCFramework stocke chaque slice séparément, éliminant les conflits d'architecture lors de la compilation. Apple recommande XCFramework pour tous les nouveaux projets et pour la migration des projets existants.
CocoaPods prend en charge XCFramework depuis la version 1.9. Dans le podspec, il suffit de spécifier spec.vendored_frameworks et spec.static_framework. Le gestionnaire résout automatiquement les dépendances en tenant compte des slices disponibles pour la plateforme du projet.
Apple ne supprime pas la prise en charge de .framework, mais recommande exclusivement XCFramework pour les nouveaux SDK. Lors de l'envoi d'une application à l'App Store avec un fat binary dans l'ancien format, des erreurs Invalid Bundle peuvent survenir en raison des architectures de simulateur, faisant de XCFramework une nécessité pratique.
À partir de Swift 5.3, les dépendances binaires dans SPM utilisent XCFramework. Package.swift spécifie l'url et la somme de contrôle du paquet binaire. SPM télécharge, vérifie l'intégrité et connecte le XCFramework comme dépendance système sans compiler le code source.
visionOS est pris en charge dans XCFramework à partir de Xcode 15. À la WWDC 2023, Apple a confirmé que le format a été étendu pour Apple Vision Pro. Le slice pour visionOS a SupportedPlatform = xros et inclut l'architecture arm64.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi