An Introduction to Swift Package Manager

In this introduction to the Swift Package Manager, you’ll build a website to display random idioms. You’ll learn how to manage projects and dependencies and how to read and change Package.swift files. By Joannis Orlandos.

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

Managing Dependencies

In this project, you would be unable to run the application without switching to the super user. For development purposes, you’ll commonly use a port different than 80. You’re usually free to use any port above port 1024 that is not already in use.

Usually, you will specify a dependency using from to set a minimum version, so that SPM can download updates of newer version of the package. But in this scenario, version 1.0.1 has the port permission problem, and the last known working version is 1.0.0. Looks like you’ll need to go back to 1.0.0.

Edit Package.swift and replace the dependency with the following to pin the dependency to exactly version 1.0.0:

.package(url: "https://github.com/raywenderlich/spm-tutorial.git", .exact("1.0.0"))

After changing the manifest, your dependencies won’t be updated automatically. To update them, you could just update your Xcode project again, but this time, run the following command in your project’s directory from Terminal:

swift package update

This command, on its own, will look for newer or different versions of your dependencies and download them as required.

You are working in Xcode to update this project, so you'll need to regenerate your Xcode project after running this command. This is necessary because dependencies can add and remove files.

Execute the following command to regenerate your project:

swift package generate-xcodeproj

Troubleshooting Dependencies

Some versions of Xcode will prompt you with the following:

Click Revert to reload the project from the disk. And if Xcode will not compile your application after this, close the window and open the project again.

This time when you build and run in Xcode, you will see Server started and listening in the console. Open a web browser, and go to localhost:8080 to check out what you made, refreshing a few times as you go.

Now you know how to run an application using Xcode. So far, so good!

Next, you’ll learn more about SPM and running swift from the terminal. Stop the application in Xcode if it is running, and switch back to Terminal.

Running From the Terminal

Now that you’ve learned how to build and run applications on macOS, you’re all set to start developing. However, server-side Swift is commonly run on Linux servers. So you’ll need to know how to compile and run applications on Linux, too.

On macOS, as long as you have Xcode 10.1 or later installed, you’re all set. If you are working in a Linux environment, you need to set up Swift as described on the Swift Download page.

There are three primary commands that you’ll work with; the most common command is swift run. This will build your application and run the resulting executable.

If there are multiple executable targets, you simply add the target name to the command:

swift run Website

The first time you run this command, SPM compiles everything first, which might take a bit of extra time, but it will compile much faster in subsequent compiles. Once you see the Server started and listening message, you’ll know it’s up and running. To stop the server, press Control + C.

Another common task is running unit tests. Don't run this for now, but the following command is the one you'll use for running the unit tests of your package:

swift test

Note: Do not run swift test as it will run the server in the background and never stop it. Testing server-side Swift projects is outside the scope of this tutorial, so while it is important to know this command, the project is not set up for testing.

Note: Do not run swift test as it will run the server in the background and never stop it. Testing server-side Swift projects is outside the scope of this tutorial, so while it is important to know this command, the project is not set up for testing.

Finally, use the following command to build your executable without running it:

swift build

Build Configurations

The above commands use the debug configuration by default. There are more configurations available; the most common one is release.

The debug configuration compiles much faster than release, but compiling a binary with the release configuration results in increased optimization.

Add --configuration release to your command to change the configuration to release, and execute it:

swift run --configuration release

This command starts the server. Navigate to http://localhost:8080 in your browser. If you see an idiom, your application is working!

Your server is up and running

However, don’t call it a day just yet. There’s still a problem to be solved!

Editing the Library

In many development scenarios, another application will be using port 8080. You’ll need to move one of the applications to another port by assigning another unused port. The imported library doesn’t support this, but you can implement it yourself!

The first step is to put the package in editable mode. Press Control + C to stop the server. Then, run the following command:

swift package edit WebsiteBuilder

This moves WebsiteBuilder into the Dependencies folder in your project. SPM will not update or change the dependency. Before you can edit the package, regenerate the Xcode project.

Tip: To quickly recall commands in Terminal, you can press the up-arrow key repeatedly in Terminal. Do this until you get back to the swift package generate-xcodeproj line, then press Return to run it again and regenerate the project.

Tip: To quickly recall commands in Terminal, you can press the up-arrow key repeatedly in Terminal. Do this until you get back to the swift package generate-xcodeproj line, then press Return to run it again and regenerate the project.

Within the Dependencies group in Xcode’s Project navigator, you’ll find a list of all dependency sources. Open Website.swift in the WebsiteBuilder dependency folder.

Remove the following line from the run() method:

let port = 8080

Also change the run() method’s signature to the following:

public func run(port: Int) throws {

Now you’ll need to specify your port. Open your own application’s main.swift file. Change the last line in that file, the one that actually runs the website, and modify the port number:

try website.run(port: 8123)

To complete this tutorial, run the application using the release configuration in Terminal with your swift run --configuration release command. Once it’s started, open the website in a browser at http://localhost:8123.

Do you see an idiom? If so, you’re done! Time flies when you’re having fun, doesn’t it?