Swift Package Manager

The Swift Package Manager is an exciting feature of Swift that is already not so new but still is not officially released. According to the swift.org overview, it should be released with Swift 3.0 in late 2016. I’m writing this post in the age of Xcode 7.3. To use SPM I installed the latest Swift 2.2 snapshot and set the path to the latest toolchain in the terminal.

export PATH=/Library/Developer/Toolchains/swift-latest.xctoolchain/usr/bin:"${PATH}"

Despite the simple concept, I found that sometimes a new package setup process may be not so obvious. That’s why I want to share my experience here.

How to setup a package

The two most important things are folder structure and the manifest file. In the example below, you can see the project that contains two modules.

The simplest way to create a Swift package is to use a command

swift build --init

By default, it will create an executable project but you can use parameters executable/library to create a library module:

swift build --init library

This will create the structure similar to the one below.

In the following example, ExecutableModule will produce an executable module, and LibraryModule will be built to a library module.

I will not describe the structure in details because a good description of the process can be found in the official documentation.

How to build a Swift module

To build a module from the console you need to navigate to the folder containing your project and run

swift build

It will create a .build folder containing your modules.

If you are building an executable module with main.swift you can run it with the following command

.build/debug/ExecutableModule

Possible errors:

error: unable to invoke subcommand: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-build (No such file or directory)

Fix:

Make sure you have the Swift 2.2 snapshot installed.

export PATH=/Library/Developer/Toolchains/swift-latest.xctoolchain/usr/bin:"${PATH}"

How to use a Swift package pushed to GitHub

To import a package to your project you need to specify the required package in the dependencies array inside the Package.swift file.

In this example, “Kitura-router” package will be imported with all its dependencies.

let package = Package(
    name: "Test",
    dependencies: [
        .Package(url: "https://github.com/IBM-Swift/Kitura-router.git", majorVersion: 0),
    ]
)

You can set ‘majorVersion: 0’ to always build the latest version of the module even if its version number is less than 1.0

How to use a local Swift package

A local git repository can be used as a package source as well as a remote repository. To use a local source in package dependencies you should set the url to the package directory.

dependencies: [
    .Package(url: "../SampleProject.git", majorVersion: 1),
]

As you can see, the version number of the package should be provided. Tagging is a most annoying feature of SPM that should be changed in future.

Tagging

One annoying feature of the current version of SPM is tagging. SPM uses tags to determine the required version number of a module. It uses it even with the local version of a package.

Make sure you’ve added a version number tag to the commit.