DEV Community

Cover image for Mastering Advanced Swift: Optionals, Collections, Closures, Protocols, and Error Handling
Rohan Joshi
Rohan Joshi

Posted on • Edited on • Originally published at rohanjsh.Medium

Mastering Advanced Swift: Optionals, Collections, Closures, Protocols, and Error Handling

Advanced Swift Concepts

Before starting, Open Xcode, Click on File => New => Playground => iOS => Blank, and create a new playground to run Swift Code.

Optionals

Swift’s powerful Optionals feature lets you save a value that that could be nil (no value).

    var optionalString: String? = "Hello"
    print(optionalString) // Output: Optional("Hello")
Enter fullscreen mode Exit fullscreen mode

Using if-let or guard-let statements, or by setting a default value, you can safely unwrap an optional:

    // if-let
    if let unwrappedString = optionalString {
        print(unwrappedString) // Safe unwrapping
    } else {
        print("The optional was nil.")
    }

    // guard-let
    func someFunction() {
        guard let unwrappedString = optionalString else {
            print("The optional was nil.")
            return
        }
        print(unwrappedString) // Safe to use 'unwrappedString' after this point
    }

    // default
    print(optionalString ?? "DefaultValue")
Enter fullscreen mode Exit fullscreen mode

Collections

Swift provides arrays, sets, and dictionaries for storing collections of values.

Array: Ordered collections of values.

    var someInts = [Int]() // An empty array
    var moreInts: [Int] = [10, 20, 30]
Enter fullscreen mode Exit fullscreen mode

Set: Collections of unique values.

    var aSet: Set<Int> = [1, 2, 3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

Dictionary: Unordered collections of key-value associations.

    var namesOfIntegers: [Int: String] = [1: "one", 2: "two", 3: "three"]
Enter fullscreen mode Exit fullscreen mode

Closures

Self-contained functional blocks called closures can be utilised and passed around within your code.

    let greetingClosure = { (name: String) in
        print("Hello, \(name)")
    }
    greetingClosure("World")
Enter fullscreen mode Exit fullscreen mode

Constants and variables from the surrounding context can be captured by closures.

Protocols

A protocol is a set of guidelines that specify the attributes, methods, and other needs necessary for a certain piece of functionality like a blueprint.

    protocol FullyNamed {
        var fullName: String { get }
    }

    struct Person: FullyNamed {
        var fullName: String
    }

    let john = Person(fullName: "John Appleseed")
Enter fullscreen mode Exit fullscreen mode

Extensions

Extensions provide an existing class, structure, enum, or protocol type new functionalities.

    extension Int {
        func squared() -> Int {
            return self * self
        }
    }
    print(3.squared()) // Output: 9
Enter fullscreen mode Exit fullscreen mode

Enums

Enums allow you to work with a set of related values in your code in a type-safe manner by defining a common type for them.

    enum Direction {
        case north
        case south
        case east
        case west
    }
    var directionToHead = Direction.west
Enter fullscreen mode Exit fullscreen mode

With features like related values, Swift enums are far more powerful than enums in many other languages.

    enum Barcode {
        case upc(Int, Int, Int, Int)
        case qrCode(String)
    }

    var productBarcode = Barcode.upc(8, 85909, 51226, 3)
Enter fullscreen mode Exit fullscreen mode

Error Handling

For the purpose of propagating, catching, modifying, and throwing recoverable errors at runtime, Swift offers first-class support.

    enum PrinterError: Error {
        case outOfPaper
        case noToner
        case onFire
    }

    func send(job: Int, toPrinter printerName: String) throws -> String {
        if printerName == "Never Has Toner" {
            throw PrinterError.noToner
        }
        return "Job sent"
    }
Enter fullscreen mode Exit fullscreen mode

Exercise: Practice With Advanced Swift

Firstly, a Swift closure that takes a string and prints it. Next, create an enum with a few possible UI states (such as loading, error, and success), and then write a function that accepts the enum as an input and outputs a message according to each state.


These language features are essential to learning Swift and becoming a proficient iOS developer because they are often utilised in UI programming, particularly when handling user interactions and asynchronous processes.

After you understand these ideas, we’ll go on to leverage UI with iOS-specific APIs, and eventually creating an entire application. Practice these ideas because they will serve as the foundation for your understanding of iOS development.

Practice. Experiment. Learn

Top comments (0)