Video

Watch the full video on YouTube:

iOS Development Guide EP02: Variables, constants and data types

Introduction

This is chapter two of our series on iOS development with Swift. After installing Xcode and touring its interface in the previous chapter, in this video we have our first real contact with the language: we create our first variables, get to know the most common data types and understand why Swift prefers an approach built around immutability.

All the code in this chapter lives in a Playground, the ideal environment to experiment without the pressure of building a full application. Here we will try things, break compilation on purpose and see what the compiler says when something does not fit.

By the end of this chapter you will know how to declare variables with var, create constants with let, work with String, Int, Double, Float and Bool, and group values into collections like Array and Dictionary.

Creating a Playground

We open Xcode and choose New Project. Instead of an application, we select Playground, because first we need to get to know the language to know what we can do with each of its features.

We save the project as 00 variables.swift inside our course folder. Once opened, we see two panels: the text editor on the left and a preview with the output of our print calls on the right.

What are variables

To explain it in a dynamic way, let’s picture the computer as a storage system: a warehouse or a store. Our variables would be the boxes or containers in that warehouse.

Those containers are labeled so we know what they hold. In programming, a variable is actually a reference: a memory address in the computer. Under the metaphor, it would be the address of the place in the warehouse where our box sits. With that address we can go and fetch what is inside.

So a variable has three parts: a name (the label), a content (what it holds) and a memory address (where it lives).

Declaring variables with var

In Swift we use the reserved word var to create variables. It always goes to the left of the name:

// var + name + assignment operator + content
var name = "Angel"

The order is: var to create the variable, a space, the name (the label of our container), the = operator and to its right the content. Put another way, we create a variable called name that contains “Angel”.

Basic data types

String: inferred typing vs explicit typing

The text “Angel” has a data type: String, a sequential chain of characters. The length of the text hardly matters, the limits are set by memory.

There are two ways to declare the variable. The first is inferred typing: Swift deduces the type for us.

// Inferred typing: Swift deduces that name is a String
var name = "Angel"

The second is explicit typing: we write the type after the name using a colon.

// Explicit typing: we force the data type
var nameExplicit: String = "Angel"

The difference matters. With explicit typing, if we try to assign an integer to a String, the compiler stops us:

// Error: cannot convert value of type 'Int' to specified type 'String'
var nameExplicit: String = 1

With inferred typing, if we change the value, Swift infers again: when we assign 2 it knows it is now an Int. That is why explicit typing is more reliable: it guarantees which type you are working with at any given moment.

One key detail: unlike languages such as TypeScript, in Swift data types are real classes, not a layer of typing on top of values. They have their own methods, their own attributes and their own ways of being extended.

Int, Double, Float and Bool

Alongside String we find the primitive types: they represent individual values used to build more complex types.

// Swift primitive types
var age: Int = 28            // integers
var weight: Double = 70.5    // decimals (Swift's preferred type)
var height: Float = 1.67     // decimals (must be written explicitly)
var isMale: Bool = true      // logical values: true or false
  • Int represents integer numbers, useful for example for an age in years.
  • Double represents decimal values, useful for a weight.
  • Float also represents decimals, for example a height, but Swift prefers to infer Double: if you write var weight = 70.5 the type will be Double. To use Float you must mark it explicitly.
  • Bool always holds true or false.

Collections: Array and Dictionary

Besides primitives, Swift offers types to represent collections.

Array

Arrays are represented with the Array type and in Swift all of their elements must be of the same type:

// Array with explicit typing
var names: Array<String> = ["Angel Rada"]

// Array with typing inferred by the compiler
var names2 = ["Angel", "Rada"]

Dictionary

Dictionaries need two data types: one for the keys and one for the values:

// Dictionary with explicit typing
var person: Dictionary<String, String> = [
    "name": "Angel",
    "last name": "Rada"
]

// Dictionary with inferred typing
var person2 = [
    "name": "Angel",
    "last name": "Rada"
]

Shorthand syntax

There is a shorter way: wrap the data type in square brackets.

// Equivalent to Array<String>
var names: [String] = ["Angel", "Rada"]

// Equivalent to Dictionary<String, String>
var person: [String: String] = [
    "name": "Angel",
    "last name": "Rada"
]

The compiler understands [String] as an array of strings and [String: String] as a dictionary of text keys and values.

Constants with let

So far we created everything with var, but when a value is not going to change over time, we are talking about a constant. And here is the big difference with JavaScript or TypeScript: in Swift we do not use const, we use let.

// let creates an immutable constant
let constantName = "Angel"

The difference between var and let is the factor of mutability:

// name was created with var: it is mutable
var name = "Angel"
name = "Rada" // no problem

// constantName was created with let: it is immutable
let constantName = "Angel"
constantName = "Rada" // compilation error

The same applies to collections. An array created with var allows its content to change:

// Mutable collection with var
var names = ["Angel"]
names.append("Rada") // ok
names[0] = "Rada"    // ok

But if we change it to let, the compiler complains as soon as we try to mutate it, whether with append, index access or a dictionary key:

// Immutable collection with let
let fixedNames = ["Angel"]
fixedNames.append("Rada") // error: fixedNames is a constant
fixedNames[0] = "Rada"    // error

let fixedPerson = ["age": "30"]
fixedPerson["age"] = "31" // error: cannot mutate a let

That is exactly the approach built around immutability that Swift prefers: if something does not need to change, it is declared with let and the compiler makes sure nobody modifies it by accident.

Int variants

Int is the standard way to handle integers, but Swift also ships variants for smaller or larger integers, such as Int8, Int16, Int32 and Int64:

// Int variants depending on the needed value range
var someSmallInteger: Int16 = 42
var someInteger: Int32 = 2_147_483_647

Each variant supports a different value range. There are tables online with the exact range of each one; in practice, Int covers most cases and you will only reach for the variants when you need to control memory usage.

Best practices

  1. Prefer let by default and use var only when the value really has to change.
  2. Take advantage of inferred typing when the type is obvious and write the explicit type when you want to make the intention clear.
  3. Use Double for decimals: Swift infers it before Float.
  4. Remember that the elements of an Array must all be of the same type.
  5. Choose the Int variant (Int8, Int16, Int32, Int64) depending on the range you need.
  6. Practice in the Playground before taking the code to a real project.

Conclusion

In this second coding chapter of the iOS with Swift series we learned what variables are, how to declare them with var and let, which are the primitive data types (String, Int, Double, Float, Bool) and how to group values into Array and Dictionary. We also saw the difference between inferred and explicit typing, and why Swift prefers immutability.

If something was not clear, leave it in the comments of the video. And if you liked the explanation, hit like and subscribe to the channel: I will keep publishing the next chapters of the series.

iOS Development Guide EP01: Install Xcode and tour its interfaceTypeScript Guide EP16: Enums and Literal Unions