Creating a Framework for iOS

Learn how to build an iOS framework, which lets you share code between apps, modularize your code or distribute it as a third-party library. By Emad Ghorbaninia.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Preparing the Swift Package

In the starter project files you already have a simple Swift Package. Navigate to /starter/3-SwiftPackage/CalendarControl and open Package.swift

Swift Package manifest

This class is the manifest for your Swift Package. You need to modify it to make CalendarControl a Swift Package.

Follow these steps and fill manifest with the right value:

This code indicates which platforms it can run on.

These are products the package provides. These can be either a library — code you can import into other Swift projects — or an executable — code you can run by the operating system. A product is a target you can export for other packages to use.

Targets are modules of code that are built independently. Here you add a path for your XCFramework.

  1. Platforms:
  2. platforms: [
      .macOS(.v10_15), .iOS(.v14), .tvOS(.v14)
    ],
    

    This code indicates which platforms it can run on.

  3. Products:
  4. products: [
      .library(
        name: "CalendarControl",
        targets: ["CalendarControl"]),
    ],
    

    These are products the package provides. These can be either a library — code you can import into other Swift projects — or an executable — code you can run by the operating system. A product is a target you can export for other packages to use.

  5. Targets:
  6. targets: [
      .binaryTarget(
        name: "CalendarControl",
        path: "./Sources/CalendarControl.xcframework")
    ]
    

    Targets are modules of code that are built independently. Here you add a path for your XCFramework.

platforms: [
  .macOS(.v10_15), .iOS(.v14), .tvOS(.v14)
],
products: [
  .library(
    name: "CalendarControl",
    targets: ["CalendarControl"]),
],
targets: [
  .binaryTarget(
    name: "CalendarControl",
    path: "./Sources/CalendarControl.xcframework")
]
Note: The first line of manifest must contain a formatted comment which tells Swift Package Manager the minimum version of the Swift compiler requires to build the package.

Finally, add your XCFramework to the project and put it under Sources:

Adding XCFramework

Congratulations! Your Swift Package is ready for distribution.

Framework hero

Large Binary and Compute Check-Sum

Although this isn’t the case for CalendarControl, a particularly massive framework will need extra care. Open up the spoiler below if you’d like to learn more about handling larger binaries.

[spoiler title=”Large Binary and Compute Check-Sum”]

If you have a large binary framework, as Apple suggested, you shouldn’t add it to your repository. Instead, you can upload it to your host and add a URL in your manifest target like this:

targets: [
  .binaryTarget(
    name: "CalendarControl",
    url: "https://example.com/CalendarControl.xcframework.zip",
    checksum: "4d4053074fd8b92f9f2f339c48980b99")
]

Here you have three inputs:

  1. Name: This is your package name.
  2. URL: Your XCFramework zip file URL.
  3. Checksum: Your Swift Package will ensure the framework zip file is the same as you made by checking this checksum.

Follow these steps to calculate the checksum:

Checksum

  1. Compress your framework and copy the zip file into Swift Package folder.
  2. In the terminal, navigate to Swift Package folder.
  3. Run the following command and generate a checksum.
swift package compute-checksum CalendarControl.xcframework.zip

Your XCFramework checksum is here. You can copy this to your manifest.

[/spoiler]

Publishing Your Swift Package

Xcode makes publishing your packages easy. Next, you’ll publish the CalendarControl Swift Package you created.

Using Xcode, open the Swift Package project. Then select Source Control ▸ New Git Repositories… from the menu bar.

Git repo

This creates a Git repository on your computer and an initial commit of your code.

Before you can publish your package for others to use, it must be available publicly. The easiest way to do this is to publish to GitHub.

If you don’t have a GitHub account you can create one for free at github.com. Then, if you haven’t done so already, add your GitHub account to Xcode by selecting Xcode ▸ Preferences in the Xcode menu. Select Accounts.

Now, click + to add a new account. Select GitHub and fill in your credentials as requested.

Add github

Open the Source Control navigator and select the CalendarControl package. Then open the context menu by either Right-clicking or Control-click.

Next, select New “CalendarControl” Remote…. You can change the visibility to Private or accept the default settings. Then click Create.

Create Remote

This creates a new repository on GitHub and automatically pushes the code there for you.

Next, set your framework’s version by creating a tag for your package. In the context menu, select Tag main…. Tag it as version 1.0.0 and click Create.

Tagging

Finally, select Source Control ▸ Push… from the Xcode menu bar. Make sure Include tags is selected. Then click Push.

This pushes the tag to GitHub where the SwiftPM can read it. Version 1.0.0 of your package is now live. :]

Pushing

Using Swift Package

Now it’s the time to use your Swift Package in the RWCalendarPicker project.

Open RWCalendarPicker again. Remove the imported CalendarControl framework from your project target:

Removing

Next, you’ll learn how to add a Swift Package to a project using Swift Package Manager.

Adding Package Dependency Using SPM

Select File ▸ Swift Packages ▸ Add Package Dependency…. Paste the Git Repository URL. The click Next.

Depending on your GitHub settings, you may need to authenticate your SSH key here. Then, under Rules, make sure Up to Next Major is selected for the version 1.0.0. Click Next.

If you want to learn more about major and minor versioning check out semver.org. After Xcode fetches the package, ensure the CalendarControl product is selected and added to the RWCalendarPicker target. Then select Finish.

Adding Swift Package

Build and run. Make sure everything runs as before.

Building

Fantastic! Now you have a remote Swift Package that you used inside a project.

Gold Medal

Where to Go From Here?

You can download the completed version of the project using the Download Materials button at the top or bottom of this tutorial.

In this tutorial, you learned how to:

  1. Extract CalendarControl from RWCalendarPicker and make a new framework.
  2. Use the CalendarControl Framework in RWCalendarPicker.
  3. Build a binary framework and use that XCFramework in RWCalendarPicker.
  4. Publish a Swift Package and use it in RWCalendarPicker.

Nice work!

From here, take a look at WWDC 2019 and 2020 videos regarding this topic:

If you have any comments or questions, please join the discussion below.