Thursday, November 26, 2020

Mastering Swift 5.3

The latest edition in my Mastering Swift series has just been released.  It has been updated for the latest release of Swift and has two new chapters.

Over the years, Mastering Swift has proved itself among developers as a popular choice as an in-depth and practical guide to the Swift programming language. This sixth edition comes with the latest features, overall revision to align with Swift 5.3, and two new chapters on building swift from source and advance operators. 

From the basics of the language to popular features such as concurrency, generics, and memory management, this in-depth guide will help you develop your expertise and mastery in the language.

As you progress, you will gain practical insights into some of the most sophisticated elements in Swift development, including protocol extensions, error handling, and closures. The book will also show you how to use and apply them in your own projects. In later chapters, you will understand how to use the power of protocol-oriented programming to write flexible and easier-to-manage code. Finally, you will learn how to add the copy-on-write feature to your custom value types, along with understanding how to avoid memory management issues caused by strong reference cycles.

By the end of this book, you will have mastered the Swift 5.3 language and developed the skills you need to effectively use its features to build robust applications.

Chapter 1Taking the first steps with Swift, will introduce you to the Swift programming language and discuss what inspired Apple to create Swift. We'll also go over the basic syntax of Swift and how to use Playgrounds to experiment and test Swift code.

Chapter 2, Swift documentation and installation, will introduce the user to the swift.org and swiftdoc.org sites and how the swift development process works.  We will go through the complete process of building swift from source and installing it on both the Linux and Mac platforms.

Chapter 3Learning about variables, constants, strings and operators, will introduce variables and constants in Swift and when to use them. There will be brief overviews of the most common variable types with examples on how to use them. We'll conclude this chapter by showing examples of how to use the most common operators in the Swift language

Chapter 4Optional Types, will explain what optional types really are, what are the various ways to unwrap them. For a developer who is just learning Swift, optional types can be one of the more confusing items to learn.

Chapter 5Using Swift collections, will explain Swift's array, set, and dictionary collection types and show examples on how to use them.

Chapter 6Control Flow, will show you how to use Swift's control flow statements. These include looping, conditional, and control transfer statements.

Chapter 7Functions, This chapter is all about functions in Swift.  We will show how to define and properly use them

Chapter 8Classes, Structures and Protocols, This chapter is dedicated to Swift's classes, structures and protocols. We'll look at what makes them similar and what makes them different.

Chapter 9Protocol and Protocol Extensions, will cover both protocols and protocol extensions in detail since protocols are very important to the Swift language, and having a solid understanding of them will help us write flexible and reusable code

Chapter 10Protocol Oriented Design, will cover the best practices of Protocol Oriented Design with Swift.  

Chapter 11Generics,  will explain how Swift implements generics. Generics allow us to write very flexible and reusable code that avoids duplication 

Chapter 12Availability and Error Handlingwill cover error handling in depth as well as the availability feature.

Chapter 13Custom Subscripting, will discuss how we can use custom subscripts in our classes, structures, and enumerations. 

Chapter 14Working with Closureswill show how to define and use closures in our code. This chapter concludes with a section on how to avoid strong reference cycles with closures

Chapter 15Advanced and Custom Operators, will show how to use bitwise and overflow operators.  We will also look at how we can create custom operators

Chapter 16Concurrency and Parallelism, will show how to use both Grand Central Dispatch and Operation Queues to add concurrency and parallelism to our applications

Chapter 17Custom Value Typeswill cover some advance techniques that the reader can use in their applications like copy-on-write and implementing the equatible protocol.

Chapter 18Memory Managementwill cover items like how Automatic Reference Counting (ARC) works, how much faster value types are as compared to reference types, strong retain cycles, weak vs strong references

Chapter 19Swift Formatting, will define a style guide for the Swift language that can be used as a template for enterprise developers who need to create a style guide

Chapter 20Adopting Design Patterns with Swift, will show you how to implement some of the more common design patterns in Swift. A design pattern identifies a common software development problem and provides a strategy for dealing with it

You can purchase a copy of my book from Amazon or from Packt Publishing.

Thursday, April 30, 2020

Compile Swift for Linux with its Toolchain and Package Manager

If you are unable to install Swift with pre-built binaries, you can compile it instead.  Compiling is a lot more complex and confusing than simply installing prebuilt binaries and I found that a lot of instructions do not build the Swift package manager which I consider to be a necessity when build anything more complex than a simple hello world application.  In this post we look at how we can build Swift with its full toolchain and package manager.

Install Dependencies

The first thing we need to do is to make sure we have all of the dependencies required installed.  The following command includes all dependencies I have needed to install on different flavors of Linux.  You will find that your distribution probably already has a lot of these preinstalled but to make sure you have everything, run this command.

sudo apt-get install git cmake ninja-build clang python uuid-dev libicu-dev icu-devtools libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config libcurl4-openssl-dev systemtap-sdt-dev tzdata rsync python-pip

If you want to build the documentation, you will need to install Sphinx as well.  This can be done with the following command:

 pip install Sphinx

Now that we have all of the dependencies installed, we need to get the swift source code.

Swift Source

To download the Swift source code, we will want to create a directory to download it too, change to that directory and then run the git command to get the source.  The following commands will download the swift source to a directory name swift-source.

mkdir swift-source
cd swift-source
./swift/utils/update-checkout --clone

Now that we have the source and cloned everything we need, lets build swift.

Build Swift 

Before you begin building Swift, know that it is going to take hours to build.  The exact time will depend on the type of system you are building it on.  The following command will build Swift, its toolchain and the package manager:

./swift/utils/build-script --preset=buildbot_swiftpm_linux_platform,tools=RA,stdlib=RA

Once this has built everything, which could take several hours, we will want to install it similar to what we did with the pre-built binaries in this post:  

Installing Swift

Now that we have built Swift from source, we are ready to install it and put it in our path so we can execute them easily.  I like to install the under the /opt directory, others prefer installing it under the /usr/local/sharedirectory.  What directory you put it under is totally up to you.  I will walk you through installing it under the /optdirectory, if you would like to put it someplace else simply replace the “/opt” in the paths with your install directory.  

Now let’s change to the /opt directory and create a directory named swift.  Once the swift directory is created, we will also need to change the permissions for the directory so we can read, write and execute files.  The following commands will do this:

cd /opt
sudo mkdir swift
sudo chmod 777 swift

The command chmod 777 swift will add read, write and execute permissions for all users of this computer.  I like to use this mode because then any user on the system can use it, however this can be considered a security issue because it also means anyone can modify the files.  Use this at your own risk and for production systems I would really look at who needs permissions for this directly and lock it down more.

Now we will need to move the Swift binaries that we downloaded to the swift directory.  To do this we will change to the swift directory, create a new directory for our build, change to the directory and copy the files over.  For this article I am building the 5.3-dev version of swift therefore I am using that for my directory name.  The following commands will do this:

cd swift
mkdir swift-5.3-dev
cd swift-5.3-dev
cp -R ~/swift-source/build/buildbot_incremental/toolchain-linux-x86_64/* ./

Now we will want to make a symlink to this directory called swift-current.  The reason for this is we will want to add an entry to our PATH environmental variable so the operating system can find the Swift executables without us needing to enter the full path.  If we set up this entry using the swift-current path rather than the swift.5.3-dev path.  This will allow us, when we install new versions of Swift, to simply change where the swift-current symlink points to and have everything work.   We will do this with the following command:

sudo ln -s /opt/swift/ swift-5.3-dev swift-current

Now we will need to create the entry in our PATH variable.  To do this you will want add the add /opt/swift/swift-current/usr/bin/ directory to the PATH variable in our .profile file located in your home directory.  Then update the environment The following commands will do this:

cd ~
echo 'export PATH=$PATH:/opt/swift/swift-current/usr/bin'  >> .profile
source ~/.profile

The last thing we need to do is to verify swift has been successfully installed. To do this, we can run the following command:

swift –version

The output should look something like this but with the version of swift that you installed

Swift version 5.2.2 (swift-5.2.2-RELEASE)
Target: x86_64-unknown-linux-gnu

Congratulations, you have now successfully installed Swift.


Installing Swift for Linux with Pre-built Binaries

The easiest and quickest way to install Swift for Linux is by installing pre-built binaries.  If you are using a LTS branch for Ubuntu, you can find links to download these binaries by going to the following page: https://swift.org/download/.  In this post we will look at how we can install Swift using these binaries however before we do that lets look at the possibility of installing Swift with pre-built packages on non-Ubuntu systems.

Install using a Linux package manger

If you are not using Ubuntu, you may still be able to install pre-built binaries through the package manager that comes with your system.  As an example, with CentOS you can very easily install swift with the following command:

sudo yum install swift-lang swift-lang-runtime.


Installing with the binaries from these package managers will be the easiest way to install Swift however what version is installed and if they stay up to date is dependent on the person that build these binaries.  To find out if your flavor of Linux has a Swift package, you will first have to determine which package manager is used by your system.  You will probably have either apt or yum as your package manager.  The easy way to determine which package manager you have installed is to run both the apt and the yum command.  After you run the command, you will see either the help message for the command if it is installed or a command not found error if the command is not installed.

Once you determine which package manager is installed, you can run one of the following commands to see if there are Swift packages for you flavor of Linux:

apt search swift-lang
yum search swift-lang

If no results are found, you could try searching for swift rather than swift-lang however you will find numerous results that are not the Swift language.  If you do have results from your search, you can install the package by using one of the following commands (Note: replace {package name} with the name of the package returned from the search):

sudo apt install {package name}
sudo yum install {package name}

To verify that Swift is properly installed once the packages are installed, look at the verifying installations section at the end of this chapter.

If swift is properly installed, then you should see the version number of the installed version of Swift.  I wish I could make these instructions were more specific however there is no way we could cover all flavors of Linux here and even if we were able to, there would be no guarantee that packages would not change tomorrow.  

Now let’s look at how we can download and install the Ubuntu binaries from the swift.org site.  

Installing using the swift.org binaries


If you ae using an LTS version of Ubuntu, the easiest way to install Swift is to install the pre-built binary, for your version of Ubuntu, from the swift.org site.  These are official release binaries built by the Swift community itself.  They release pre-binaries for Ubuntu with all official releases of Swift and also for the latest development branch if you want to try the latest and greatest. 

To install Swift with these binaries, the first thing we need to do is to download them from the swift.org site.  In your favorite browser go to the following URL,  https://swift.org/download/ and you should see a screen similar to this:


As you can see from this screenshot, that the latest official released version of Swift, at the time this book was written, is 5.2.2.  To download the pre-built binaries for Swift, you simply need to click on the version of Ubuntu that you are using and it will start the download. In this case I would download a file named swift-5.2.2-RELEASE-ubuntu18.04.tar.gz.  

The name starts off with the word swift because it contains the pre-built binaries for the Swift language, followed by the version number.  Next we see the word RELEASE because this is an official release version of Swift.  If it wasn’t an official release version, we would see the word DEVELOPMENT instead.  The end of the name tells us what platform the pre-built binaries are built for.  In this case they are built for Ubuntu 18.04.

Now we will need to unzip and untar the file.  To do this we need to run the following command:

tar -xzf swift-5.2.2-RELEASE-ubuntu18.04.tar.gz

You will want to substitute the file name in the previous command with the name of the file that you downloaded.  Once this command has finished, you should have a directory with the same name as the original file except it will not have the .tar.gz suffix. 

Before we install these binaries and set up our path, we will want to install the dependencies.  The following command will install the required dependencies:

sudo apt-get install clang libicu-dev

The required dependencies may change with future releases of Swift.  The same page that you downloaded Swift from also contains the list of dependencies.  You can verify that no additional dependencies are needed by referring to that page.

Now that the dependencies are installed, we are ready to install the Swift binaries and put them in our path so we can execute them easily.  I like to install the under the /opt directory, others prefer installing it under the /usr/local/share directory.  What directory you put it under is totally up to you.  I will walk you through installing it under the /opt directory, if you would like to put it someplace else simply replace the “/opt” in the paths with your install directory.  

Now let’s change to the /opt directory and create a directory named swift.  Once the swift directory is created, we will also need to change the permissions for the directory so we can read, write and execute files.  The following commands will do this:

cd /opt
sudo mkdir swift
sudo chmod 777 swift

The command chmod 777 swift will add read, write and execute permissions for all users of this computer.  I like to use this mode because then any user on the system can use it, however this can be considered a security issue because it also means anyone can modify the files.  Use this at your own risk and for production systems I would really look at who needs permissions for this directly and lock it down more.

Now we will need to move the Swift binaries that we downloaded to the swift directory.  To do this we will change to the swift directory and then move the untarred binaries, that should be located in the Downloadsdirectory, to the swift directory.  The following commands will do this:

cd swift
mv ~/Downloads/swift-5.2.2-RELEASE-ubuntu18.04 ./

Now we will want to make a symlink to this directory called swift-current.  The reason for this is we will want to add an entry to our PATH environmental variable so the operating system can find the Swift executables without us needing to enter the full path.  If we set up this entry using the swift-current path rather than the swift.5.2.2-RELEASE-ubuntu18.04 path.  This will allow us, when we install new versions of Swift, to simply change where the swift-current symlink points to and have everything work.   We will do this with the following command:

sudo ln -s /opt/swift/ swift-5.2.2-RELEASE-ubuntu18.04  swift-current

Now we will need to create the entry in our PATH variable.  To do this you will want add the add /opt/swift/swift-current/usr/bin/ directory to the PATH variable in our .profile file located in your home directory.  Then update the environment variables  The following commands will do this:

cd ~
echo 'export PATH=$PATH:/opt/swift/swift-current/usr/bin'  >> .profile
source ~/.profile

The last thing we need to do is to verify swift has been successfully installed. To do this, we can run the following command:

swift –version

The output should look something like this but with the version of swift that you installed

 Apple Swift version 5.3-dev (LLVM a60975d8a4, Swift afe134eb2e)
Target: x86_64-unknown-linux-gnu

Congratulations, you have now successfully built and installed Swift.  Now to verify that the package manager was successfully built and installed, run the following commands:

mkdir test
cd test
swift package init

If everything was successfully built you should see out similar to this:

Creating library package: test
Creating Package.swift
Creating README.md
Creating .gitignore
Creating Sources/
Creating Sources/test/test.swift
Creating Tests/
Creating Tests/LinuxMain.swift
Creating Tests/testTests/
Creating Tests/testTests/testTests.swift
Creating Tests/testTests/XCTestManifests.swift

You are now ready to go.