Framework and XCFramework are the two ways we can distribute our code as binary. These are packages which includes multiple architecture variants built for iOS, macOS, watchOS, tvOS and iPadOS.
Framework and XCFramework both are pretty similar in what they do but actually different in terms of how they package the architecture variants.
Frameworks are actually universal/Fat framework, which means all the different architectures are clubbed together in a single binary.
Framework | XCFramework |
---|---|
Framework contains one binary file with multiple architecture | XCFramework contains multiple binary files with multiple architecture |
You can create Framework or Fat/Universal Framework using -lipo command | You can create XCFramework using Xcodebuild -create-xcframework command |
Framework is not supported in M1 chip mac, because it can’t have two arm64 variants. One arm64 for iOS device and another for arm64 for M1 chip macOS simulator. | XCFramework is supported in M1 chip mac, because it can have two arm64 variants. One arm64 for iOS device and another for arm64 for M1 chip macOS simulator. |
We can’t distribute Framework using Swift Package Manager | We can distribute XCFramework using Swift Package Manager |
Framework contains one set of header files | XCFramework contains one set of header files for each architecture variants |
Framework contains one set of debug symbols (dSYMs and BCSymbolMaps) | XCFramework contains one set of debug symbols (dSYMs and BCSymbolMaps) for each architecture variants |
Logo of Framework is | Logo of XCFramework is |
Distribution through cocoapod can be done using the following podspec spec.source_files = 'Reachability/*.swift' spec.vendored_frameworks = "{spec.name}.framework" spec.preserve_paths = "* “ | Distribution through cocoapod can be done using the following podspecspec.vendored_frameworks = "{spec.name}.xcframework" spec.preserve_paths = "*" |
Steps to create Framework?
Step-1: Build for Device using Xcode
Step-2: Build for Simulator using Xcode
Step-3: Locate the .framework variants of simulator and device
Step-4: Run the following command. (pass on the correct path based on your system)
lipo -create ios-simulator/sample.framework ios-device/sample.framework -output ~/Desktop/sample.framework
Step-5: That’s all, You got the Framework which have simulator and device variants, eg.- arm64, x86_64 etc.
How to create XCFramework?
Step-1: Build for Device using Xcode
Step-2: Build for Simulator using Xcode
Step-3: Locate the .framework variants of simulator and device
Step-4: Run the following command. (pass on the correct path based on your system)
xcodebuild -create-xcframework ios-simulator/sample.framework ios-device/sample.framework -output ~/Desktop/sample.xcframework
Step-5: That’s all, You got the XCFramework which have simulator and device variants, eg.- arm64, x86_64 etc. but in different folder structure.
Apple Developer have on article on basics of XCFramework.
I have written a detailed article on How to create XCFramework and details about it.
How different is Podspec for Framework and XCFramework?
Podspec for Framework:
Pod::Spec.new do |spec|
spec.name = 'SampleFramework'
spec.version = '3.1.0'
spec.license = { :type => 'BSD' }
spec.homepage = 'https://github.com/ssatpathy/SampleFramework'
spec.authors = { 'Saurav Satpathy' => 'kumarsaurav.15@gmail.com' }
spec.summary = 'Sample framework'
spec.source = { :git => 'https://github.com/ssatpathy/Reachability.git', :tag => 'v3.1.0' }
spec.module_name = 'Sample'
spec.swift_version = '4.0'
spec.ios.deployment_target = '9.0'
spec.osx.deployment_target = '10.10'
spec.source_files = 'SampleFramework/*.swift'
spec.vendored_frameworks = "{spec.name}.framework"
spec.preserve_paths = "*
spec.framework = 'SystemConfiguration'
spec.ios.framework = 'UIKit'
spec.osx.framework = 'AppKit'
spec.dependency 'SomeOtherPod'
end
Podspec for XCFramework:
Pod::Spec.new do |spec|
spec.name = 'SampleFramework'
spec.version = '3.1.0'
spec.license = { :type => 'BSD' }
spec.homepage = 'https://github.com/ssatpathy/SampleFramework'
spec.authors = { 'Saurav Satpathy' => 'kumarsaurav.15@gmail.com' }
spec.summary = 'Sample framework'
spec.source = { :git => 'https://github.com/ssatpathy/Reachability.git', :tag => 'v3.1.0' }
spec.module_name = 'Sample'
spec.swift_version = '4.0'
spec.ios.deployment_target = '9.0'
spec.vendored_frameworks = "{spec.name}.xcframework"
spec.preserve_paths = "*"
spec.framework = 'SystemConfiguration'
spec.ios.framework = 'UIKit'
spec.osx.framework = 'AppKit'
spec.dependency 'SomeOtherPod'
end
Eric Lanz wrote a great article on challenges of XCFramework.
Apart from these steps we can also create XCFramework using fastlane. Fastlane have a plugin called create_xcframework.
Pingback: How to create XCFramework using Fastlane - bitMountn Inc.