Mastering Swift 3 - Linux

2 (1 reviews total)
By Jon Hoffman
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Taking the First Steps with Swift

About this book

Swift is a modern, fast, and safe programming language created by Apple. Writing Swift is interactive and fun, the syntax is concise yet expressive, and the code runs lightning-fast. Swift’s move to open source has been embraced with open arms and has seen increased adoption in the Linux platform.

Our book will introduce you to the Swift language, further delving into all the key concepts you need to create applications for desktop, server, and embedded Linux platforms. We will teach you the best practices to design an application with Swift 3 via design patterns and Protocol-Oriented Programming.

Further on, you will learn how to catch and respond to errors within your application. When you have gained a strong knowledge of using Swift in Linux, we’ll show you how to build IoT and robotic projects using Swift on single board computers. By the end of the book, you will have a solid understanding of the Swift Language with Linux and will be able to create your own applications with ease.

Publication date:
January 2017
Publisher
Packt
Pages
380
ISBN
9781786461414

 

Chapter 1. Taking the First Steps with Swift

Ever since I was 12 years old and wrote my first program in the BASIC language, programming has been a passion for me. Even as programming became my career, it always remained more of a passion than a job, but over the past few years, that passion has waned. I was unsure why I was losing that passion. I attempted to recapture it with some of my side projects, but nothing really brought back the excitement that I used to have. Then, something wonderful happened! Apple announced Swift, which is an exciting and progressive language that has brought a lot of that passion back and made programming fun for me again. Now that Apple has released Swift for Linux, I can use it for most of my projects.

In this chapter, you will learn the following topics:

  • What is Swift?

  • Some of the features of Swift

  • How to get started with Swift

  • What are the basic syntaxes of the Swift language?

 

What is Swift?


Swift is Apple's new programming language that was introduced at the Worldwide Developers Conference (WWDC) in 2014, alongside the integrated development environment Xcode 6 and iOS 8. Swift was arguably the most significant announcement at WWDC 2014, and very few people, including Apple insiders, were aware of the project's existence prior to it being announced. In this initial release of Swift it could only be used to develop applications for the Apple platforms.

It was amazing, even by Apple's standards, that they were able to keep Swift a secret for as long as they did, and no one suspected that they were going to announce a new development language. At WWDC 2015, Apple made another big splash when they announced Xcode 7 and Swift 2. Swift 2 was a major enhancement to the language. During that conference, Chris Lattner said that a lot of enhancements were based directly on feedback that Apple received from the development community. It was also announced at WWDC 2015 that Apple would be releasing Swift as open source, and they would be offering a port for Linux.

In December 2015, Apple officially released Swift as an open source project with the swift.org site dedicated to the open source Swift community. The Swift repository is located on Apple's github page (http://github.com/apple). The Swift evolution repository (https://github.com/apple/swift-evolution) tracks the evolution of the Swift language by documenting all of the proposed changes. You can also find a list of proposals that were accepted and rejected in this repository. If you are interested in understanding where Swift is heading, then you should check out this repository. It is interesting to note that Swift 3 contains several enhancements that were proposed by the community.

Swift 3 is a major enhancement to the language and is NOT source-compatible with previous releases. It contains fundamental changes to the language itself and to the Swift standard library. One of the main goals of Swift 3 is to be source-compatible across all platforms, so the code that we write for one platform will be compatible with all other platforms that Swift supports. This means that the code we develop for Mac OS will also work on Linux.

Development on Swift was started in 2010 by Chris Lattner. He implemented much of the basic language structure with only a few people being aware of its existence. It wasn't until late 2011 that other developers began to really contribute to Swift, and in July 2013, it became a major focus of the Apple Developer Tools group.

There are a lot of similarities between Swift and Objective-C. Swift adopts the readability of Objective-C's named parameters and its dynamic object model. When we refer to Swift as having a dynamic object model, we are referring to its ability to change at runtime. This includes adding new (custom) types and changing/extending the existing types.

While there are a lot of similarities between Swift and Objective-C, there are also significant differences between them as well. Swift's syntax and formatting are a lot closer to Python than Objective-C, but Apple did keep the curly braces. I know that Python people would disagree with me, and that is all right because we all have different opinions, but I like the curly braces. Swift actually makes the curly braces required for control statements such as if and while, which eliminates bugs, such as the goto fail in Apple's SSL library, which Apple patched in 2014.

Swift's features

When Apple said that Swift is Objective-C without the C, they were really only telling us half the story. Objective-C is a superset of C and provides object-oriented capabilities and a dynamic runtime to the C language. This means that, with Objective-C, Apple needed to maintain compatibility with C, which limited the enhancements it could make to the Objective-C language. As an example, Apple could not change how the switch statement functioned and still maintains the C compatibility.

Since Swift does not need to maintain the same C compatibility as Objective-C, Apple was free to add any feature/enhancement to the language. This allowed Apple to include the best features from many of today's most popular and modern languages, such as Objective-C, Python, Java, Ruby, C#, and Haskell.

The following chart shows a list of some of the most exciting enhancements that Swift includes:

Swift feature

Description

Type inference

Swift can automatically deduce the type of the variable or constant, based on the initial value.

Generics

Generics allow us to write the code only once to perform identical tasks for different types of objects.

Collection mutability

Swift does not have separate objects for mutable or nonmutable containers. Instead, you define mutability by defining the container as a constant or variable.

Closure syntax

Closures are self-contained blocks of functionality that can be passed around and used in our code.

Optionals

Optionals define a variable that might not have a value.

Switch statement

The Switch statement has been drastically improved. This is one of my favorite improvements.

Multiple return types

Functions can have multiple return types using tuples.

Operator overloading

Classes can provide their own implementation of existing operators.

Enumerations with Associated values

In Swift, we can do a lot more than just defining a group of related values with enumerations.

Before we can look at the Swift language itself, we need to download and install it. Let's look at how we can install Swift.

Installing Swift 3 for Linux

The following instructions were current when this book was written and works for both Ubuntu 15.10 and Ubuntu 16.04 LTS. The most up-to-date installation instructions can be found on the swift.org installation page: https://swift.org/getting-started/#installing-swift.

The first step in installing Swift is to install clang and configure it. The following are the commands:

sudo apt-get update
sudo apt-get install clang-3.6
sudo update-alternatives -install /usr/bin/clang clang
    /usr/bin/clang-3.6 100
sudo update-alternatives -install /usr/bin/clang++ clang++
    /usr/bin/clang++-3.6 100

If you forget to do the update-alternatives commands, you will receive an error: invalid inferred toolchain error when you try to build a package. Forgetting to run the update-alternatives commands is a very common error.

Now that we have the correct clang installed, we need to download Swift. You can download the latest version from the swift.org download page. The link for this page is: https://swift.org/download/.

Once you have downloaded Swift, you can install it in the location of your choice; however, you will want to avoid installing it off the root directory because that may overwrite the /usr directory. As a personal preference, I like to install Swift in the /opt directory. The following instructions will show how I install Swift.

Tip

Anytime you see {swift version}, substitute it for the version information of the Swift you are installing.

1. Go to the /opt directory:

cd /opt

2. Create a directory to hold this and all future Swift versions:

sudo mkdir swift

3. Change to the swift directory, and copy the downloaded swift file to this location:

cd swift
sudo cp -R ~/Downloads/swift-{swift version}.tar.gz ./

4. Gunzip and untar the swift file:

tar -zxvf  swift-{swift version}.tar.gz

5. The last command should have created a new directory that contains the Swift files. We will now want to create a symbolic link to this directory indicating that it is our current version of Swift:

sudo ln -s /opt/swift-{swift version} swift-current

6. All of the files in the swift directory are owned by the root user. If you attempt to build a Swift package with the package manager, while all of the files are owned by root, you will receive a permission denied error. The easiest way to fix this is to change the ownership of the Swift files to your user. If you want to give permission for multiple users to use Swift, you can add write permissions for all users. Instructions for both options are listed here and you only need to follow one of them:

//Change ownership of the Swift files
sudo chown -R {username}:{username} swift-{swift version}
//Alternatively change write permission
sudo chmod -R +x swift-{swift-version}

7. Now, we need to add Swift to our path. To do this you will have to edit your ~/.profile file and add the following line to it:

PATH=/opt/swift/swift-current/usr/bin:$PATH

8. You can either start a new terminal session to pick up the changes or run the following command in your current session:

. ~/.profile

To verify everything is good, run the swift -version command, which should output your new version of Swift. When a new version of Swift is released, install it to the /opt/swift directory and then change the swift-current symbolic link to point to this new version.

Swift language syntax

The Swift language uses modern concepts and syntax to create very concise and readable code. There is also a heavy emphasis on eliminating many common programming mistakes. Before we look at the Swift language itself, let's take a look at some of the basic syntax of the language.

Comments

When we write comments for Swift code, we can use the traditional double slash // for single-line comments and the /* and */ for multi-line comments. If we want to use the comments to also document our code, we need to use the triple slash ///.

When we write our code on a Linux computer, we do not have access to the Xcode IDE. However, since the code we write for Linux can be compatible with Apple's platforms it is a good habit to comment our code in such a manner that it will be recognized in the Xcode IDE.

Tip

This book is about using Swift for Linux, therefore we try to avoid any functionality that requires an Apple computer or an iPad. We do however use Playgrounds and Xcode in this section to illustrate how comments can be used for documentation on the Apple platform so we will understand why the format is important.

To document our code, we can use the following specific fields that Xcode recognizes:

  • Parameter: When we start a line with - parameter {param name}, Xcode recognizes this as the description for a parameter

  • Return: When we start a line with - return:, Xcode recognizes this as the description for the return value

  • Throws: When we start a line with - throws:, Xcode recognizes this as the description for the errors that this method may throw

This example shows both single-line and multi-line comments and how to use the comment fields:

To write good comments, I would recommend using single-line comments within a function to give quick one-line explanations of your code. We will then use multi-line comments outside functions and classes to explain what the function and types do. The preceding Playground shows a good use of comments. When we use proper code comments, as we did in the preceding screenshot, we can take advantage of the documentation feature within Xcode. If we hold down the option key and then click on the function name anywhere in our code, Xcode will display a popup with a description of the function.

The next screenshot shows what that popup looks like:

This screenshot shows the documentation feature of Xcode if we hold down the option key and then click on the myAdd() method. We can see that the documentation contains six fields. These fields are as follows:

  • Declaration: This is the function's declaration (that is, its signature)

  • Description: This is the description of the function as it appears in the comments

  • Parameters: The parameter descriptions are prefixed with the - Parameters: tag in the comment section

  • Throws: The throws description is prefixed with the - throws: tag and describes what errors are thrown by the methods

  • Returns: The return description is prefixed with the - returns: tag in the comment section

  • Declared In: This is the file that the function is declared in, so that we can easily find it

Semicolons

You may have noticed, from the code samples so far, that we are not using semicolons at the end of lines. Semicolons are optional in Swift; therefore, both lines in the following code are valid in Swift:

print("Hello from Swift") 
print("Hello from Swift"); 

For style purposes, it is strongly recommended that you do not use semicolons in your Swift code. If you are really set on using semicolons in your code, then be consistent and use them in every line of the code; however, Swift will not warn you if you forget them. I will stress again that it is recommended that you do not use semicolons in Swift.

Parentheses

In Swift, parentheses around conditional statements are optional; for example, both if statements in the following code are valid:

var x = 1 
 
if x == 1 { 
    print("x == 1") 
} 
 
if (x == 1) { 
    print("x == 1") 
} 

For style purposes, it is recommended that you do not include the parentheses in your code unless you have multiple conditional statements on the same line. For readability purposes, it is a good practice to put parentheses around the individual conditional statements that are on the same line.

Curly brackets

In Swift, unlike most other languages, curly brackets are required after conditional or loop statements. This is one of the safety features that is built into Swift. Arguably, there have been numerous security bugs that might have been prevented if the developer had used curly braces. These bugs could also have been prevented by other means, such as unit testing and code reviews, but requiring developers to use curly braces, in my opinion, is a good security standard.

The following code shows how to use curly brackets:

let x = 1 
 
//Valid 
if x == 1 { 
    print("x == 1") 
} 
 
//Not Valid 
if x == 1 
    print("x == 1") 

Assignment operators do not return a value

In most other languages, the following line of code is valid, but it is probably not what the developer meant to do:

if (x = 1) {} 

Tip

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you purchased. If you purchased this book from elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

In Swift, this statement is invalid. Using an assignment operator (=) in a conditional statement (if and while) will throw an error. This is another safety feature built into Swift. It prevents the developer from forgetting the second equal to sign (=) in a comparison statement.

Spaces are optional in conditional and assignment statements

For both conditional (if and while) and assignment (=) statements, white spaces are optional. Therefore, in the following code, both The i block and The j block code blocks are valid:

//The i block 
var i=1 
if i==1 { 
    print("HI") 
} 
 
//The j block 
var j = 1 
if j == 1 { 
    print("HI") 
} 

Tip

For style purposes, I would recommend adding the white spaces (such as The j block) for readability, but as long as you pick one style and are consistent, either style should be acceptable.

 

Hello World


All good computer books that are written to teach a programming language have a section that shows a user how to write a Hello World application. This book is no exception. In this section, we will show you how to write a Hello World application with Swift.

Let's begin by creating a new file named main.swift. The main.swift file is a special file in Swift and is the entry point for our application. It is the only file that can contain top-level code. Top-level code is the code that is not part of a function or type (enumeration, class, or structure). All of the code for our Hello World application is considered top-level code.

In Swift, to print a message to the console, we use the print() function. In its most basic form, we would use the print function to print out a single message as shown in the following code:

print("Hello World") 

Usually, when we use the print() function, we want to print more than just static text. We can include the value of variables and/or constants using a special sequence of characters, \( ), or by separating the values within the print() function with commas. The following code shows how to do this:

var name = "Jon" 
var language = "Swift" 
 
var message1 = "Welcome to the wonderful world of " 
var message2 = "\(name) Welcome to the wonderful world of \(language)!" 
 
print(name, message1, language, "!") 
print(message2) 

In order to compile this code, it will need to be in a file name main.swift. You can use any text editor, like emacs or VI, to create this file. Once the main.swift file is created, we will need to build our Hello World application. Type the following line in the same directory where the main.swift file is located:

    swiftc main.swift

Once the swift compiler finishes building the application, we will have an executable file named main in our directory. We can run the file using the following command:

    ./main 

If all goes well, you can see the following output:

Jon Welcome to the wonderful world of Swift!
Jon Welcome to the wonderful world of Swift!

We will look at the swift and swiftc commands later in this chapter.

We can also define two parameters in the print function that change how the message is displayed in the console. These parameters are the separator and terminator parameters. The separator parameter defines a string that is used to separate the values of the variable/constant in the print() function. By default, the print() function separates each variable/constant with a space. The terminator parameter defines which character is inserted at the end of the line. By default, the newline character is added at the end of the line.

The following code shows how we could create a comma-separated list that does not have a newline character at the end:

var name1 = "Jon" 
var name2 = "Kim" 
var name3 = "Kailey" 
var name4 = "Kara" 
 
print(name1, name2, name3, name4, separator:", ", terminator:"") 

There is one other parameter that we can add to our print() function. This is the toStream parameter. This parameter will let us redirect the output of the print() function. In the following example, we redirect the output to a variable named line:

var name1 = "Jon" 
var name2 = "Kim" 
var name3 = "Kailey" 
var name4 = "Kara" 
 
var line = "" 
 
print(name1, name2, name3, name4, separator:", ",  terminator:"", to:&line) 

The print() function was simply a useful tool for basic debugging, but now we can use the new enhanced print() function a lot more.

 

Executing Swift code


In the next couple of sections, we will look at the various ways in which we can execute our Swift code. We could easily write a complete book on these tools; however, in this section, we will give a brief overview of each tool, so you will be aware of how to use them to execute your code or build your applications. After reading these sections, you should be able to build and execute the examples in this book, as well as your own applications.

 

Swift and the Swift REPL


There are a couple of ways in which you can quickly experiment with Swift code. The first is the Swift interactive Read Evaluate Print Loop (REPL). The REPL is a command line tool that evaluates our code as we write it. Developers who are used to interpreting languages will be comfortable using this tool.

To start the REPL, you will need to open a terminal prompt and enter the following command:

swift

You will be greeted with a prompt similar to the following:

Welcome to Swift version 3.0 ({your-swift-version}). Type :help for
    assistance
1>

From here, we can type in any Swift statement and hit Enter. The REPL will immediately execute our code. The following is an example:

1>  var x = 10
x: Int = 10
2>  x += 5
3>  print(x)
15

To exit the REPL, type the following command:

:quit

We can also quickly test a Swift source file using the swift command. To try this out, create a file named Hello.swift, and put the following code in it:

print("Hello") 

Now let's run the following command to execute this source file:

swift Hello.swift 

You should see the message Hello printed to the console. The REPL and Swift commands are extremely powerful tools, and you can do a lot more than just prototyping new code. If you find these tools useful, I would recommend spending time learning about the various advanced features.

 

Swift compiler


When we run our code using the swift command, or the Swift REPL tool, we are running the code as we would run a typical interpreted script such as a Bourne Again SHell (BASH) or Python script. This is really nice if we want to use Swift as a scripting language but if we want to build applications with Swift, we will need to compile our code into an executable form. To do this, we can use the Swift compiler.

Let's see how we would use the Swift compiler to build the Hello World example that we created earlier. If you recall from that example, we had to create a main.swift file. While using a main.swift file is not required for an application that only contains a single source file, it is required for applications that contain multiple source files. The Swift compiler will look for the main.swift and use it as the entry point for the application, similar to how a C compiler uses the main() function.

Tip

It is a good habit, when all of our code is contained in one file, to name that file main.swift.

To build the Hello World application that we created earlier, we would need to run the following command in the same directory that the main.swift file is in:

swiftc main.swift

This command should only take a second or so to run. Once it is completed, we should have an executable file named main. If your application contains multiple files, you can list them one by one as follows:

swiftc main.swift file1.swift file2.swift file3.swift

If you want to change the name of the output file, you can use the -o option as follows:

swiftc main.swift file1.swift file2.swift -o myexecutable

There are a number of command line options that you can use with the swift compiler. However, if you find that you are using a lot of command line options and making a complex compiler statement, you may want to look at the Swift Package Manager.

 

Using the Swift Package Manger


According to Apple, the Swift Package Manager is defined as:

A tool for managing the distribution of Swift code. It's integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

The first part of the previous statement means that the Swift Package Manager can be used to manage the distribution of modules. Some applications may have all their code organized into a single module. More complex applications may separate their code into different modules. As an example, if you were developing an application that communicates with another device over Bluetooth, you may want to put the Bluetooth code into a separate module, so you can reuse it in other applications.

The Swift Package Manager will manage module or application dependencies and will automate the process of downloading, compiling, and linking these dependencies. This allows us to concentrate on our code rather than figuring out how to write complex build scripts to compile our applications or modules.

A package consists of the Swift source files and a manifest file called Package.swift. The manifest file defines the package's name and contains instructions on how to build the package. We can customize the manifest file to declare build targets or dependencies, include or exclude source files, and specify build configurations for the module or application.

Let's look at how we can use the Package Manager to create a simple application. Firstly, we need to decide how we will name the application. For our example, we will use the name PMExample. Let's create a directory with that name and then change to that directory:

mkdir PMExample
cd PMExample

Now, we need to build the framework that the Package Manager needs. To do this, we will run the following command:

swift package init

This command will create both the Sources and Tests directory. It will also create a number of files including the Package.swift manifest file and also a file in the Sources directory with the same name as your application. If you look at the Package.swift manifest file, it should look as follows:

import PackageDescription 
let package = Package( name: "PMExample" ) 

This is the most basic manifest file, and it simply defines the name for the package. We will look at this manifest file in greater depth in Chapter 13, Using C Libraries with Swift.

Now, let's look at the PMExample.swift that was created for us in the Sources directory. It should contain code similar to the following code:

struct PMExample {       
   var text = "Hello, World!" 
} 

Let's add some code to this file, so it contains the following code:

struct PMExample {       
   var text = "Hello, World!" 
   func sayHello() { 
      print(text) 
   } 
} 

All we did in this example was add a method that prints Hello, World! to the console.

Tip

Don't worry if you do not understand this code yet. We are looking to get you familiar with the Package Manager and the compiler, so you feel comfortable compiling the code examples in this book.

Now let's add the main.swift file to the Sources directory. This will be the entry point to our application. Add the following code to this file:

let example = PMExample() 
example.sayHello() 

Now, go back to the PMExample directory, and run the following command to build the PMExample application.

swift build

This will build the application. If all is well, we will have an executable application in the PMExample/.build/debug directory named PMExample.

Note that, in the PMExample.swift file, all of the code was contained in the PMExample structure, whereas the code in the main.swift file was top-level code. Remember what we noted earlier: the main.swift file is the only file that can contain top-level code.

We only scratched the surface of what the Package Manager can do in this section. We will look at it further in Chapter 13, Using C Libraries with Swift.

When all of the source code is in one file, it will be much easier to use the swift compiler to build your executable code; however, once your application grows past that single source file, I would recommend looking at the Package Manager to manage your dependencies and your builds.

 

Editors for Swift


You can use pretty much any text editor such as VI, Emacs, or gedit to write your Swift code. It can be pretty painful at times to use these text editors to write code, especially when you are accustomed to using standard IDEs, which come with code completion. If you want to spend a little money, you could get an IDE (such as CLion) that comes with a Swift plugin, but there is one free code editor that works really well with Swift. That editor is Visual Studio Code from Microsoft.

Yes, Microsoft makes a free code editor that can run on Linux and can edit Swift files (are you as surprised as I was?). I was pretty skeptical at first, but once I started using it, I realized that it was the best Swift editor for Linux that I could find at the time I wrote this book. To download Visual Studio Code, you can go to https://code.visualstudio.com, and select the download link. Keep in mind that, when we use Visual Studio Code to write applications in Swift, it is nothing more than a code editor. We cannot run or debug our code from within Visual Studio Code.

Hopefully, as more developers use Swift on Linux, we will begin to see some good developer tools emerge.

 

Summary


In this chapter, we showed you how to start and use Playgrounds to experiment with Swift programming. We also covered the basic Swift language syntax and discussed proper language styles. The chapter concluded with two Hello World examples.

In the next chapter, we will see how to use variables and constants in Swift. We will also look at the various data types, and how to use operators in Swift.

About the Author

  • Jon Hoffman

    Jon Hoffman has over 20 years' experience in the field of Information Technology. Over those 20 years, Jon has worked in the system administration, network administration, network security, application development, and architecture arenas. Currently, he works as an Enterprise Software Manager at Syntech Systems. He has developed extensively for the iOS platform since 2008. This includes several apps that he has published in the App Store, apps that he has written for third parties, and numerous enterprise applications. Some of Jon's other interests are playing basketball, kayaking, and working out with his daughters. Jon also really enjoys Tae Kwon Do, where he and his oldest daughter earned their black belts together early in 2014 and are currently 3rd-degree Black Belts.

    Browse publications by this author

Latest Reviews

(1 reviews total)
I give the author one extra star for guts. Another author, well received and known for decades for his books on Linux, and recently also for his books on Swift, Kofler, writes in his latest book on Swift that he considers Swift on Linux unusable. This book goes throug the usual hoops to introduce a new language. You can observe the usual lack of editing and guidance at Packt publishing in the authors choice and presentation of advanced material. I do not care for the specifics of the beaglebone hardware in a book about swift on linux. Anyone interested in programming languages has seen the inappropriateness of the Gang-of-Four design patterns when applied to modern programming languages - they are a child of their time and the C++ language at that time.