Blog

Learning SwiftPM – The Swift Package Manager

03 Dec, 2018
Xebia Background Header Wave

The Swift Package Manager (SwiftPM) is a tool for building your Swift applications. Just like other build tools like Maven or Gradle, SwiftPM manages project dependencies, and can build, test and publish packages.
SwiftPM provides a standard way to build Swift applications and is a replacement for build tools like CocoaPods and Carthage. SwiftPM is a cross platform build system that is available for MacOS and Linux.
Apple published an introduction video Getting to Know Swift Package Manager – Apple WWDC 2018 and SwiftPM has been documented.
In this blog we are going to create a new application project, and create a small application. You don’t have to know any Swift to follow along.

Some assumptions

Before we move on, I will assume that you have a Mac, and have some experience with programming languages,

Installation

To install Swift and the SwiftPM on a Mac, open the App Store, search for Xcode, which is free and install it.

$ swift --version
Apple Swift version 4.2.1 (swiftlang-1000.0.42 clang-1000.10.45.1)
Target: x86_64-apple-darwin18.2.0

Commands

SwiftPM provides the following commands:

# Build sources into binary products
$ swift build

# Build and run tests
$ swift test

# Build and run an executable product
$ swift run

# Initialize a new package
$ swift package init
# Perform operations on Swift packages
$ swift package

# fetch Packages from Package.swift
$ swift package fetch

# update package source code
$ swift package update

# Generate Xcode Project 
$ swift package generate-xcodeproj

Create Hello World Package

$ pwd
~/projects

$ mkdir helloworld
$ cd helloworld

$ swift package init --type executable

SwiftPM created the following package structure. Source files are put in ‘Sources’ and test files are put in ‘Tests’.

.
├── Package.swift
├── README.md
├── Sources
│   └── helloworld
│       └── main.swift
└── Tests
    ├── LinuxMain.swift
    └── helloworldTests
        ├── XCTestManifests.swift
        └── helloworldTests.swift

Swift Package

The most important file is ‘Package.swift’ which describes the package and consists of dependencies, targets and products, and is declared with the Swift syntax.

/ swift-tools-version:4.2
// The swift-tools-version declares the minimum 
// version of Swift required to build this package.

import Packagecontent

let package = Package(
    name: "helloworld",
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
    ],
    targets: [
        // Targets are the basic building blocks of a package. 
        // A target can define a module or a test suite.
        // Targets can depend on other targets in this package, 
        // and on products in packages which this package depends on.
        .target(
            name: "helloworld",
            dependencies: []),
        .testTarget(
            name: "helloworldTests",
            dependencies: ["helloworld"]),
    ]
)

The executable

The main executable is stored in ‘Sources/helloworld/main.swift’ and contains a single print statement.

print("Hello, world!")

To run the application type:

$ swift run
Compile Swift Module 'helloworld' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/helloworld
Hello, world!

If you get the following error then you can fix it like so:

$ swift run
error: terminated(72): xcrun --sdk macosx --find xctest output:

# fix the error
$ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

$ swift run
Compile Swift Module 'helloworld' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/helloworld
Hello, world!

Generate an Xcode project

To generate a Xcode project type:

# create xcode project
$ swift package generate-xcodeproj

# open project in xcode
$ open helloworld.xcodeproj/

When the project has been loaded by xcode, press CMD+R to run hello world.

Dependencies

Dependencies are modules that are required by code in the package. A dependency provides products in the form of libraries. A dependency consists of a relative or absolute URL to the source of the package and version. SwiftPM downloads and builds everything that is needed to satisfy the entire dependency graph of the application.

Target

Targets are the basic building blocks of packages. A target describes how to build a set of source files into either a module or a test suite. Targets can depend on other targets of the same package, and on products exported from other packages, declared as dependencies.

Product

Products are executables or libraries. Products are assembled from the build artifacts of one or more targets.

Packages

Packages provide libraries to other packages by defining products. Packages are stored in git repositories and their versions are represented by git tags.

Conclusion

In this blog, we have installed Xcode, which comes with SwiftPM. We have created a simple helloworld application, created an Xcode project. Next we have launched helloworld project from the console and from Xcode.

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts