avatarWendy Liga

Summary

Swift 5.3 introduces the ability to include compiled frameworks as binary dependencies in Swift Package Manager (SPM), expanding its capabilities to support enterprise software and closed-source libraries.

Abstract

The introduction of binary dependencies in Swift 5.3's Swift Package Manager marks a significant advancement for the Swift ecosystem. Previously, SPM only supported source-code libraries, limiting its use with closed-source software. With this update, developers can now incorporate compiled frameworks, specifically in the xcframework format, into their Swift projects. This feature is exclusive to Apple operating systems for now but is expected to expand to other platforms in future Swift versions. The process involves adding a .binaryTarget to the SPM target, and it supports both zip and raw xcframework files. The article also touches on the security implications of binary dependencies, emphasizing the importance of verifying artifacts and the potential risks of network-hosted binaries, which can be mitigated by using checksums. The feature is demonstrated with an example project available on GitHub.

Opinions

  • The author, Wendy Liga, views the addition of binary dependencies as a "fantastic" enhancement, particularly for enterprise software that is often closed-source.
  • The use of xcframework is highly recommended due to its support for multiple architectures and platforms, as well as the elimination of the need to slice x86_64 before App Store uploads.
  • There is an expressed hope that future Swift versions will extend binary dependency support beyond Apple OS to include Linux and Windows.
  • The article suggests that while source-based dependencies are generally more trusted, binary dependencies have their own security considerations, such as tampering, which can be addressed with checksum verification.
  • The author provides a practical example project to illustrate the new feature, indicating a preference for hands-on learning and demonstration.

How to Add Compiled Frameworks in Swift Package Manager

Swift 5.3 brings binary dependency or compiled frameworks to SPM

Photo by Erda Estremera on Unsplash

At last, a long-awaited feature comes to Swift. Swift 5.3 will enable you to add binary dependencies in Swift Package Manager. Why does this sound fantastic? Because before Swift 5.3, SPM (Swift Package Manager) only enabled source-code libraries as a dependency, which meant that lots of enterprise software (which often comes as closed-source) or closed-source libraries couldn’t be added as a dependency in SPM, like Firebase or Google Analytics.

SE-0272 by Braden Scothern, Daniel Dunbar, and Franz Busch brings binary dependencies capability to Swift 5.3, which means you can add compiled frameworks to your SPM. But keep in mind that only xcframework format is supported for now. (Other types of frameworks were still under discussion when this article was being written. See more detail here).

What is xcframework ?

xcframework is a format that Apple introduced back in WWDC 2019, where it was discussed in “Binary Frameworks in Swift.”

There are several advantages of using xcframework, like multiple architectures and platforms (including simulator type), and no slicing x86_64 before uploading to AppStore.

You should know how to use xcframework because SPM only supports this. Unless you’ve already compiled one, skip this section. I suggest you watch the WWDC 2019 session above.

Note: Because Swift 5.3 only allows xcframework, this feature will only work on an Apple OS (iOS, macOS, tvOS, etc). I hope that a future Swift version will add this feature to Linux and Windows.

How to Use

Start by adding a new .binaryTarget in your SPM target.

let package = Package(
   name: "AwesomeLibrary",
   ...
   targets: [
      .target(
         name: "AwesomeLibrary",
         dependencies: ["Logging"]
      ),
      .binaryTarget(name: "Logging", path: "artifacts/Logging.xcframework"
      ),
      ...
   ]

SPM supports both zip and raw xcframework files for binary dependency. If you used zip, make sure the xcframework is located at the root of the archive.

There are two ways to add a binary target.

With URL

You can add a binary target from a URL, such as GitHub Release, GitHub Packages, GitLab, Bitbucket, Artifactory, Nexus, etc.

.binaryTarget(
   name: "Logging",
   url: "https://github.com/wendyliga/compiled-framework-spm/releases/download/0.0.1/Logging.xcframework.zip",
   checksum: "c246c715ac7f6fae9ef0a89e758a8514644071a164985b1e95d344a684d84621"
)

Note: With Swift 5.3, you can generate checksum by executing swift package compute-checksum <path-to-zip>. You need to make sure to download the binary first, to compute the checksum.

Raw File

On the other hand, you can add the binary by placing it in the source:

.binaryTarget(name: "Crypto", path: "artifacts/Crypto.xcframework")

Note: The path to xcframework starts from the root of the project (same as Package.swift).

Consideration

Swift doesn’t do verification of the format of the artifacts (binary dependency), which means you should make sure to provide a correct and valid artifact.

From the security perspective, comparing the trust level between source-based vs. binary dependency, naturally, source-based dependency will be higher since you can inspect the code. However, source-based dependency can have its own security issues as well.

Binary dependency also has its own problem that we should mitigate, for example, binary dependency hosted on the network. There will always be a risk of tempering. Swift reduces this by comparing the checksum of the binary you set with the one from the network. The hash also stored in the package resolves to avoid the vendor changing the binary in a later version without anyone noticing.

Example Project

All examples in this article can be found in this example project: wendyliga/compiled-framework-spm

The End

Swift 5.3 supports the compiled framework as a dependency in SPM. This opens the way for broader use cases.

Swift 5.3 also brings the capability to add resource files or non-compiled files to SPM, for example, JSON, mp3, or HTML. I’ve discussed this in a previous article, “How to Add Resources in Swift Package Manager.”

All that’s left is for me to say thanks for your time to read the article. I hope you can use this feature in your SPM Project.

Programming
Swift
iOS
Open Source
Mobile
Recommended from ReadMedium