DEV Community

Andrew Davis
Andrew Davis

Posted on

Swift for Web Developers

Swift has become a standard language for iOS development and is becoming a popular language for server side programming as well. My previous programming experience is mostly with PHP and JavaScript, so Swift was a whole new world when I started. I’m writing this post to give web developers coming from PHP, Python or Ruby a head start on how to use Swift.

Installation

MacOS

Installing Swift on a Mac is super easy. Just install Xcode! It has a great playgrounds feature for trying out the language.

Linux

To use Swift on Linux, just follow the instructions on Swift.org to download and run the compiler. Alternatively, a Docker image is available for running Swift.

Windows

If you are on Windows 10, you could install Swift in the Linux Subsystem, but the easiest method would be to install the Docker image mentioned above.

Where is My Semi-colon?

print("Hello, world!")
Enter fullscreen mode Exit fullscreen mode

The first thing you will notice is that Swift doesn’t require semi-colons at the end of each line, similar to Ruby or Python. Swift was built with both scripting languages and compiled languages in mind, so you will see different features of both types in the language.

Also, similar to Ruby and Python, you don’t have to use parentheses in conditionals, but you do use brackets to surround the contents of the block like Java and PHP.

if true {
    print("It is true")
}
Enter fullscreen mode Exit fullscreen mode

Swift uses the same structure for loops.

let fruits = ["Apple", "Pear", "Orange"]
for fruit in fruits {
    print("My favorite fruit is: \(fruit)")
}
Enter fullscreen mode Exit fullscreen mode

let vs var

In Swift, data names can be declared with two different words: let and var. Unlike ES6 JavaScript, let is for constants and var is for regular variables. The value of a let constant cannot be changed after it is set, but a var can be changed as needed.

If you write the following code, you will get an error:

let name = "Andrew"
name = "not Andrew"
Enter fullscreen mode Exit fullscreen mode

But, the following is acceptable:

var count = 1
count = 2
Enter fullscreen mode Exit fullscreen mode

The Swift compiler will give you a warning if you create a variable and then never change it, so it is best practice to start with a constant and change it to a variable only when it needs to become something else.

Swift Loves Types

Everything in Swift is statically typed, but the types are inferred like Go or Rust. Type inference basically means that the compiler figures out the type of a variable based on its initial value. So, if you try to create a constant or variable without a type defined, you must set it’s value immediately so the compiler know what type it is.

For example, if you run this code, you will get an error.

let favoriteMovie
favoriteMovie = "Return of the Jedi"
Enter fullscreen mode Exit fullscreen mode

You have to either declare the constant type or set the constant immediately.

let favoriteMovie: String
favoriteMovie = "Return of the Jedi"

let secondFavoriteMovie = "The Empire Strikes Back"
Enter fullscreen mode Exit fullscreen mode

Swift has types for all standard pieces of data: Int String Float Double Bool and more.

Parameter Names!

One of my favorite features of Swift is parameter naming. When you create a function and name the parameters, the code calling the function has to name the parameters as well.

func sayHello(greeting: String) {
    print(greeting)
}

sayHello(greeting: "Hola!")
Enter fullscreen mode Exit fullscreen mode

Once you get used to it, it makes your functions much more expressive. If you don’t want to have named parameters, you can put an _ in front of the name to omit it.

func sayGoodbye(_ goodbye: String) {
    print(goodbye)
}

sayGoodbye("Adios!")
Enter fullscreen mode Exit fullscreen mode

In the Swift standard library, you will see functions written both ways depending on the situtation so that is a good reference to use to write your own functions.

What Is Up with the Question Marks?

If you have read any Swift code before, you probably have noticed several instances where a question mark is used. A question mark is used to create a special type and it basically means the value can be either a type or nil. For example, if a variable is declared like var optional: String?, it means optional can be either a String or nil.

Now, optionals require a little more work to get the value. To use a variable with an optional type, you have to unwrap the value.

let optional: String? = "I am an optional"
if let value = optional {
    print(value)
}
Enter fullscreen mode Exit fullscreen mode

By using an if statement, you are verifying that the value in the optional is not nil and if so, it is set to value to be used within the if block.

You can also unwrap an optional by using a guard statement.

enum OptionalError: Error {
    case optionalIsNil
}

let value: String? = nil
guard let name = value else {
    throw OptionalError.optionalIsNil
}
Enter fullscreen mode Exit fullscreen mode

A guard statement attempts to unwrap the value into the name constant, but if it returns nil, it runs the content of the block. In this case, because value is nil, the guard block throws a customer error indicating something went wrong.

Optionals can be confusing the first time you use them and you may be asking, why use them then? The goal of optionals, is to make sure your code handles every situation where your constants and variables could be nil. Let’s say that you have a function which gets the current user from a session, you will want to handle the situation where the session is empty.

func getCurrentUser(session: Session) -> User? {
    if session.has("currentUser") {
        return session.get("currentUser")
    }

    return nil
}

let session = Session()
if let user = getCurrentUser(session: session) {
    print(user.name)
}
Enter fullscreen mode Exit fullscreen mode

In this case, getCurrentUser could return nil so we are only printing the user’s name if the value returned from the function actually is a User object. If we didn’t check for nil, we would have a runtime error because no name would exist. In the end, the goal of optionals is to make your code more correct.

Struct vs Class

As you start coding in Swift, you will notice that there are two constructs that look almost the same. Here is an example:

struct CarSize {
    var height: Double
    var width: Double
    var length: Double

    init(height: Double, width: Double, length: Double) {
        self.height = height
        self.width = width
        self.length = length
    }

    func getArea() -> Double {
        return width * length
    }
}

class Car {
    var make: String
    var model: String
    var color: String

    init(make: String, model: String, color: String) {
        self.make = make
        self.model = model
        self.color = color
    }

    func getType() -> String {
        return "\(make): \(model)"
    }
}

let carSize = CarSize(height: 10, width: 10, length: 20)
let car = Car(make: "Chevrolet", model: "Corvette", color: "Red")
Enter fullscreen mode Exit fullscreen mode

Both structs and classes are used to create custom types that can contain properties and methods. So what is the difference?

First, only a class can inherit from another class. A struct cannot inherit from a struct. If you require any type of inheritance, then you must use a class.

Second, instances of a class are passed by reference and instances of a struct are passed by value. Basically, that means they are stored in memory differently. When you create an instance of a class, the variable holding the instance does not actually contain the instance, it contains a memory id which is a reference to where the instance exists in memory. A variable holding an instance of a struct, actually holds the struct, not just a reference. Therefore, when you pass a class instance into a function, the function receives a reference to an object, but when you pass a struct instance into a function, it receives a copy of the struct. There are advantages and disadvantages to either scenario, so choosing a struct or class depends on what you are trying to accomplish.

In the end, structs are typically used for wrapping simple data values, like the CarSize in the example and classes are used for anything else which may include types that change often or have mutating methods. Apple recommends using classes in most cases.

Conclusion

I hope this quick rundown helps you understand some of the Swift concepts more quickly. I recommend reading Apple’s The Swift Programming Language book to learn more. Please post a comment if you any questions.

Happy Swifting!

Top comments (4)

Collapse
 
rhymes profile image
rhymes

For a second I thought it was a tutorial on how to use Swift for web development but judging from the "session" example up there I suspect you have used it. How is it? It would be nice to hear your opinion about "server side Swift"

Also I find optionals very interesting, null is not the easiest problem to solve in designing a programming language. You example also hints of using optionals for a sort of pattern matching style of programming, is it possible?

Collapse
 
restoreddev profile image
Andrew Davis

I have explored the web side of Swift a little, but only using small examples. I used a web framework called Vapor that seems pretty solid, but is still young. My gut reaction to Swift on the web is that it’s almost there, but still not worth using instead of Ruby, Python or PHP yet. Mainly because of the lack of maturity. I’m hoping it will get there soon though, because I really like the type safety and flexibility combo you get from Swift.

There is a whole side of Swift that is more functional that I didn’t discuss (it would make for a good post). Swift has tuples and enums which are used often with case statements to do pattern matching like Elixir/Erlang.

Collapse
 
gdahboy profile image
gdahboy

as i have read many other articles , i think swift best-use in api or web-apps that need an asynchronies functionality ... so comparing it to PHP i don't think that's true but comparing it to node , that's hell yes !! . Maybe in one or two year we will see perfect (a framework for swift server-side ) or vapor (another swift framework for server-side ) leading in GitHub .

Collapse
 
rhymes profile image
rhymes

Thanks, very interesting! Now I just need to find the time to learn another programming language :-D