Distribute your XCFramework — How to create a XCFramework

Oğuzhan Karakuş
Plus Minus One
Published in
5 min readDec 29, 2022
Photo by Taras Shypka on Unsplash

Are you tired of dragging & dropping the same code to every new project you create? XCFramework is here to help! In this article, we’ll show you how to create and distribute your own XCFramework, making it easier to reuse your code across multiple projects.

At PlusMinusOne, we develop, maintain, and deploy numerous iOS applications. We often use Xib and Storyboard to create and layout view objects in our apps, but we also configure these views programmatically. This requires us to write the variable names of the view objects we have created frequently. To address this problem, we created auxiliary extensions for the view classes provided by UIKit, inspired by the Builder Design Pattern.

However, adding these helper extensions to our other apps by drag and drop seems a bit lazy. In this article, I’d like to tell you how to create a XCFramework and distribute it via CocoaPods and SPM.

Before we dive into the main topic, let me briefly introduce PMOUISetter to you. PMOUISetter is a useful framework that allows us to configure view objects we have created in a chain way. It is also easy to use. If you’d like to learn more about it, you can find it here.

Why do we need framework?

XCFramework is a powerful tool for iOS developers who are working on multiple projects and want to efficiently reuse their custom frameworks and libraries. By creating and distributing your own XCFramework, you can eliminate the need for copy-pasting code and save time during the build process. Additionally, because frameworks are precompiled, they don’t add extra load to your projects, resulting in faster build times. Consider using XCFramework to streamline your development process and make it easier to reuse your code across multiple projects.

So let’s start building the framework.

Creating a XCFramework

First, let’s click on File>New>Project via Xcode. The Choose a template for your new project screen will appear, let’s choose the Framework from here.

Choose a template for your new project

In this article, I will proceed by choosing the team part as none.

This is the final version of our very useful project.

I will proceed with Dynamic Library in this article. If you want to change it, you can find it by searching Mach-O Type under build settings.

The Dynamic Library links when the application is first launched and increases the launching time, but does not increase the size of the application by much.
On the other hand, Static Library increases the size of the application but does not increase the application launch.

For ABI stability, we need to set the Build Libraries for Distribution value to Yes.

If we do not do this, when a new swift version is published, we will have to compile and distribute our framework in the new swift version.

Finally, we need to archive our XCFramework for iOS devices and Simulators. I will share a script with you to speed up this process and not drown in terminal commands.

#!/bin/sh

# -------------- config --------------

# Uncomment for debugging
set -x

# Set bash script to exit immediately if any commands fail
set -e

moduleName="your-module-name"

iphoneosArchiveDirectoryPath="/$moduleName-iphoneos.xcarchive"
iphoneosArchiveDirectory="$( pwd; )$iphoneosArchiveDirectoryPath"

iphoneosArchiveDirectoryPath="/$moduleName-iphonesimulator.xcarchive"
iphoneosSimulatorDirectory="$( pwd; )$iphoneosArchiveDirectoryPath"

outputDirectory="$( pwd; )/$moduleName.xcframework"

## Cleanup
rm -rf $iphoneosArchiveDirectory
rm -rf $iphoneosSimulatorDirectory
rm -rf outputDirectory

# Archive
xcodebuild archive -scheme $moduleName \
-archivePath $iphoneosArchiveDirectory \
-sdk iphoneos \
SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES

xcodebuild archive -scheme $moduleName \
-archivePath $iphoneosSimulatorDirectory \
-sdk iphonesimulator \
SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES

## XCFramework
xcodebuild -create-xcframework \
-framework "$iphoneosArchiveDirectory/Products/Library/Frameworks/$moduleName.framework" \
-framework "$iphoneosSimulatorDirectory/Products/Library/Frameworks/$moduleName.framework" \
-output $outputDirectory

## Cleanup
rm -rf $iphoneosArchiveDirectory
rm -rf $iphoneosSimulatorDirectory

Adding this script to the project directory and go to that directory in the terminal and run the sh GenerateXCFramework.sh command will be enough for us to create a framework.

We have finished our new XCFramework, now we can move on to the distribution phase.

Let’s Distribute our XCFramework via CocoaPods

Actually, distributing your custom framework through CocoaPods is quite easy. To do so, you will need to create a .podspec file in your project directory and include information about your framework, such as its name, version, and dependencies. In this case, the .podspec file would be named “VeryUsefulFramework.podspec”. Next, push the .podspec file and your framework to your GitHub repository.

You can edit this .podspec file according to your own case.

Pod::Spec.new do |s|
s.name = "VeryUsefulFramework"
s.version = "0.0.1"
s.summary = "VeryUsefulFramework: VeryUsefulFramework"
s.description = "your description"
s.homepage = "https://github.com/oguzhankarakus/VeryUsefulFramework.git"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "Oguzhan Karakus" => "your@mail.com" }
s.source = { :git => "https://github.com/oguzhankarakus/VeryUsefulFramework.git", :branch => "main", :tag => "#{s.version}" }
s.vendored_frameworks = "VeryUsefulFramework.xcframework"
s.platform = :ios
s.swift_version = "5.7"
s.ios.deployment_target = '16.0'
s.requires_arc = true
end

We are ready to publish our XCFramework.

To distribute your custom framework through CocoaPods, you will first need to register as a user on the CocoaPods website. After completing the registration process, CocoaPods will send you an email with further instructions on how to finish the registration. Simply follow the instructions in the email to complete the process.

Keep in mind that you will need to have a valid email address and GitHub account in order to register on CocoaPods. Once you have completed the registration process, you will be able to submit your custom framework for distribution through CocoaPods and make it available for installation by other developers

$ pod trunk register orta@cocoapods.org 'Orta Therox' --description='macbook air'

Then we enter this command, the magic happens :D

$ pod trunk push

Publish our XCFramework via SPM

We only need package.swift file to publish our XCFramework via SPM.

// swift-tools-version:5.6
import PackageDescription

let package = Package(
name: "VeryUsefulFramework",
platforms: [
.iOS(.v11)
],
products: [
.library(
name: "VeryUsefulFramework",
targets: ["VeryUsefulFramework"])
],
targets: [
.binaryTarget(
name: "VeryUsefulFramework",
path: "VeryUsefulFramework.xcframework")
])

“// swift-tools-version:5.6” is not only comment line, it really defines swift tools version

When we pushed the package file to our repo on GitHub, we also distributed it with SPM.

To learn more about our development experiences, you can have look at our medium page. At Plus Minus One, we love to learn and share our experiences. We hope this article makes your life easier 🙏🏻

--

--