XCFramework é um formato binário da Apple que combina bibliotecas para iOS, macOS, tvOS e watchOS em um único pacote. Foi projetado para substituir o .framework e eliminar os problemas de fat binaries ao compilar para diferentes arquiteturas de simulador e dispositivo. De acordo com a Apple WWDC 2019, o XCFramework se tornou o formato obrigatório para distribuição de SDK que suportam múltiplas plataformas, substituindo completamente a abordagem ultrapassada de binários universais.
Principais pontos
XCFramework é um formato de empacotamento para bibliotecas e frameworks binários apresentado pela Apple na WWDC 2019. O objetivo principal é criar um único bundle que contenha versões compiladas de uma biblioteca para todas as plataformas e arquiteturas de destino.
Antes do XCFramework, os desenvolvedores usavam .framework com fat binaries que combinavam múltiplas arquiteturas através do utilitário lipo. Essa abordagem causava problemas: ao compilar um projeto para o simulador, o fat binary continha tanto a arquitetura do simulador quanto a do dispositivo, levando a erros ao enviar a compilação para a App Store. Os desenvolvedores precisavam escrever fases Run Script para remover arquiteturas desnecessárias.
De acordo com a Documentação do Desenvolvedor da Apple (2024), o XCFramework suporta todas as plataformas do ecossistema Apple: iOS, iPadOS, macOS, tvOS, watchOS, visionOS e aplicativos Catalyst. Cada plataforma recebe um slice separado dentro do pacote, eliminando conflitos de arquitetura e simplificando a distribuição de SDK.
XCFramework é utilizado em três cenários principais: distribuição de SDK fechados para desenvolvedores terceiros, distribuição de módulos nativos para Flutter e React Native, e publicação de bibliotecas que exigem pré-compilação. O formato é obrigatório para todos os novos SDK publicados no ecossistema Apple.
Os desenvolvedores escolhem o XCFramework quando o código fonte não pode ser divulgado, quando a biblioteca utiliza algoritmos proprietários ou quando é necessária proteção de licença. Ao contrário do Swift Package Manager, que trabalha com código fonte, o XCFramework entrega arquivos binários já compilados.
O problema do fat binary era que um binário universal continha múltiplas arquiteturas em um único arquivo Mach-O. Ao compilar um aplicativo para o simulador, o Xcode incluía tanto a arquitetura arm64 do dispositivo quanto a x86_64 do simulador — a App Store aceitava apenas a arquitetura do dispositivo.
A solução tradicional envolvia adicionar uma fase Run Script chamando lipo para remover arquiteturas do simulador da compilação final. Essa abordagem era frágil e quebrava com atualizações do Xcode ou quando novas arquiteturas surgiam (por exemplo, arm64 para o simulador no Apple Silicon).
De acordo com Swift.org (2023), a equipe do Swift Package Manager encontrou inicialmente esse problema ao tentar suportar dependências binárias. O XCFramework resolveu isso no nível do formato: cada slice é uma pasta separada com um Info.plist descrevendo a plataforma e arquitetura de destino. O Xcode seleciona automaticamente o slice necessário durante a compilação, sem exigir pós-processamento.
Cada slice no XCFramework contém apenas uma combinação de plataforma e arquitetura. Por exemplo, ios-arm64 contém o binário apenas para dispositivos iOS, e ios-x86_64-simulator apenas para o simulador Intel Mac. O Xcode seleciona automaticamente o slice correto, eliminando a necessidade de scripts de remoção de arquiteturas e reduzindo o risco de erros de compilação.
O slice ios-arm64-x86_64-simulator foi introduzido para suportar Macs com Apple Silicon. Anteriormente, o simulador exigia um binário separado para arm64 (Apple Silicon) e x86_64 (Intel). O XCFramework permite um fat binary dentro de um único slice de simulador — esta é a única exceção onde o fat binary é justificado.
Um pacote XCFramework é um diretório com extensão .xcframework, contendo um Info.plist no nível superior e pastas com slices binários. Cada slice inclui uma biblioteca .framework ou .a para uma plataforma específica.
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
O Info.plist do pacote contém a chave AvailableLibraries, listando LibraryIdentifier, LibraryPath e SupportedPlatform para cada slice. O Xcode lê este arquivo ao adicionar um XCFramework ao projeto e configura automaticamente os caminhos de busca e a fase Embed Frameworks.
Cada slice é um .framework completo ou uma biblioteca estática com seu próprio Info.plist. Isso permite que o XCFramework suporte tipos mistos: bibliotecas estáticas para algumas plataformas e frameworks dinâmicos para outras, embora na prática um tipo seja usado para todos os slices.
A criação de um XCFramework é feita através do xcodebuild -create-xcframework. O comando recebe bibliotecas .framework ou .a já compiladas para cada plataforma e as combina em um único pacote.
O processo consiste em duas etapas: primeiro, os binários são compilados para cada plataforma de destino, depois são empacotados em um XCFramework. Para a compilação, são utilizados os flags de destination padrão do 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
O flag -create-xcframework foi introduzido no Xcode 11. O comando cria automaticamente a estrutura de diretórios correta e gera um Info.plist com a descrição de todas as plataformas. Se algum dos .framework estiver danificado ou compilado com a arquitetura errada, o xcodebuild emite um erro na fase de validação.
Para CI/CD, utiliza-se um script shell que automatiza a compilação para todas as plataformas e a criação do XCFramework. Uma abordagem popular é um wrapper na forma de Makefile ou Fastlane lane com parametrização de scheme e caminho de saída.
# 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"
Esse script é executado em um pipeline de CI (GitHub Actions, Bitrise, Jenkins) após a aprovação nos testes. O XCFramework resultante é arquivado e carregado como um artefato de lançamento ou publicado através de um gerenciador de dependências como CocoaPods usando pod spec.
Integrar um XCFramework em um projeto Xcode não requer configuração manual de caminhos de busca. Basta arrastar o .xcframework para a seção Frameworks, Libraries, and Embedded Content nas configurações Gerais do target.
Ao contrário do .framework, o XCFramework não requer adicionar uma fase Run Script para remover arquiteturas de simulador. O Xcode determina automaticamente os slices disponíveis e inclui apenas os necessários para o esquema de compilação atual. Para um dispositivo físico, usa-se o slice ios-arm64; para o simulador — 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)
}
Para CocoaPods, a integração é feita através de um podspec com vendored_frameworks e uma lista de plataformas suportadas. O gerenciador de dependências determina automaticamente quais slices são necessários para o projeto. Muitos SDKs comerciais — Firebase, Adjust, AppsFlyer — migraram para o XCFramework para simplificar a instalação.
Swift Package Manager e XCFramework não são concorrentes, mas sim complementares. O SPM trabalha com código fonte e compila as dependências a cada compilação do projeto. O XCFramework fornece binários prontos sem exigir compilação no lado do consumidor.
Com o lançamento do Swift Package Manager 5.3, a Apple adicionou suporte para dependências binárias — agora o SPM pode baixar um XCFramework como dependência remota. O Package.swift especifica a URL do artefato binário e sua soma de verificação para validação.
De acordo com a documentação do Swift Package Manager (2024), dependências binárias são recomendadas para SDKs que não divulgam o código fonte, ou para bibliotecas cujo tempo de compilação é desproporcionalmente longo. Para projetos de código aberto, a distribuição de código fonte via SPM é preferida.
| Critério | XCFramework | Swift Package Manager |
|---|---|---|
| Formato | Binário (.xcframework) | Código fonte |
| Proteção de código | Completa | Nenhuma |
| Tempo de compilação | Mínimo (cópia) | Depende do volume de código |
| Flexibilidade de plataformas | Todas as plataformas Apple | Depende do Package.swift |
| Integração | Arrastar e soltar ou SPM | Package.swift |
Perguntas frequentes
.framework é um formato legado que contém um fat binary com arquiteturas de dispositivo e simulador. O XCFramework armazena cada slice separadamente, eliminando conflitos de arquitetura durante a compilação. A Apple recomenda o XCFramework para todos os novos projetos e para migração dos existentes.
CocoaPods suporta XCFramework desde a versão 1.9. No podspec, basta especificar spec.vendored_frameworks e spec.static_framework. O gerenciador resolve automaticamente as dependências, levando em conta os slices disponíveis para a plataforma do projeto.
A Apple não remove o suporte ao .framework, mas recomenda exclusivamente o XCFramework para novos SDKs. Ao enviar um aplicativo para a App Store com um fat binary no formato antigo, podem ocorrer erros de Invalid Bundle devido às arquiteturas de simulador, tornando o XCFramework uma necessidade prática.
A partir do Swift 5.3, as dependências binárias no SPM usam o XCFramework. O Package.swift especifica a url e o checksum do pacote binário. O SPM baixa, verifica a integridade e conecta o XCFramework como uma dependência de sistema sem compilar o código fonte.
visionOS é suportado no XCFramework a partir do Xcode 15. Na WWDC 2023, a Apple confirmou que o formato foi estendido para o Apple Vision Pro. O slice para visionOS tem SupportedPlatform = xros e inclui a arquitetura arm64.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.