Lukas Pistrol Logo

Lukas Pistrol

Swift: Tips and Tricks for Beginners

You've just started out learning Swift? Great job! But there are some quick ways to make your life as a Swift developer so much easier. These 6 tips will help you write cleaner code instantly. Let's get right in:

Inline if-else

For sure you encountered this situation already. You want to set a variable to a value under a certain condition and otherwise the value should be different. In Swift this could look something like this:

if condition {
  someValue = 10.0
} else {
  someValue = 0.0
}

But for such a simple task wasting 5 lines of screen real-estate is not perfect. What if I tell you that you can achieve the same with just one line of code? Just type your variable name equals and then add the condition you would normally write inside the if statement followed by a question mark. Then you enter the value for when the condition is true followed by a colon and then the value for when the condition is false:

someValue = condition ? 10.0 : 0.0

Note that this should only be used for simple if statements to maintain readability. So don't chain those statements together although it's possible.

Omit return keyword (sometimes)

When writing closures or functions you often want to return some values. You probably already learned to call the return keyword followed by the value you want to return. When your function is very short and can fit into one statement you can simply omit the return keyword altogether.

func randomInt() -> Int {
  Int.random(0...100)
}

var randomBool: Bool {
  Bool.random()
}

As you can see both the function and the computed property contain only one statement and Swift automatically concludes, that this is the value you want to return. If you really want to save space you can even write those closures in one line.

func randomInt() -> Int { Int.random(0...100) }

var randomBool: Bool { Bool.random() }

Internal & external function parameter labels

Unlike Java or C-like languages, Swift has external function parameter labels. This means that you can easily see which paramter is which. But sometimes it's already clear what the parameter will be based on context so you can choose to not show it at all.

func square(num: Int) -> Int {
  num * num
}

func cube(number num: Int) -> Int {
  num * num * num
}

func quadruple(_ num: Int) -> Int {
  num * num * num * num
}

square(num: 2) // returns 4
cube(number: 2) // returns 8
quadruple(2) // returns 16

The square function has one argument label called num which has to be written inside the function header whenever you want to call the function.

The cube function has two labels inside the function header. The first one is the external label, the second one is the internal label. Sometimes you want to have a different label visible to the "outside" compared to the label you use inside your function body. As you can see at the bottom, the label for the cube function is called number.

If you want to call the function without a label you can just leave the first parameter label empty by writting an under-score.

Function parameter default values

Sometimes you want a function that has a default value for one of its parameters but in some cases you want to override that value. This can easily be done by setting the paramter to some value inside the function header like below:

func multiply(_ num1: Int, num2: Int = 2) -> Int {
  num1 * num2
}

multiply(2, num2: 5) // returns 10
multiply(3) // returns 6

As you can see the function can be called with one or two parameters. When the second paramter is not set by the function call it defaults to the number 2.

Private setter, public getter

When creating a model struct or class you often want some values to be readable from outside but also writeable from the inside. For example a score value for a Game model. The view should be able to see the score but on itself cannot set it. This would happen only from inside the struct's logic.

Simply declaring it as a var will enable reading and writing to that value from both inside and outside. Setting it to private will disable reading and writing to the variable from the outside.

As a solution you can set the variable private (set). This means the setter of this var is private and the getter is public.

struct Game {
  private (set) var score: Int
}

Bonus

Altough "print-debugging" is not the most elegant way to debug some misbehaving code, we all end up doing it from time to time. And to distinguish the newly added print statements we often end up with something like this:

print("Helloooooooooooo")
/*
*
*
*
*/
print("Helloooooooooooo 2")

But there is a much easier way to make your print statements standout: just add emoji to the beginning of the statement.

print("🔴 Your print statement")
print("🟢 Your print statement")
print("❗️❌ Your print statement")

To add emoji to any text input field in macOS simply go to Edit>Emoji & Symbols. Alternatively press ⌃ + ⌘ + ␣ or Globe + E on newer keyboards

Where to go from here?

I hope you learned something new today or at least remembered something you've already learned earlier. Have a look at my other articles and I hope I'll see you again soon!

Happy coding!

Another article you might like: