@Article {

    @Intro(title: "Learn Swift") {
        Get to know concepts of the Swift programming language useful for _Adwaita for Swift_ and find additional resources.
    }

    @ContentAndMedia {
        # Learn Swift
        This is a quick overview over the Swift features relevant for _Adwaita for Swift_.
        It's not intended to teach Swift to beginners, instead, it can be used for finding online material, to check whether you know the required concepts, and as a reference for later in the tutorial.
        The official Swift tour is available [here](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/guidedtour) and there's a more detailed tutorial starting with [The Basics](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics).
        You'll find links to relevant chapters in the "Additional information" boxes after every section on this page.

        Other great resources are [100 Days of Swift](https://www.hackingwithswift.com/100), [Swift for C++ Practitioners](https://www.douggregor.net/posts/swift-for-cxx-practitioners-value-types/), [Swift Playgrounds](https://developer.apple.com/swift-playgrounds/) (Apple platforms only), and [WWDC videos](https://developer.apple.com/videos/swift/).

        If you prefer, continue the tutorial without worrying about those Swift concepts, and learn Swift while learning how to create apps.

    }

    @ContentAndMedia {
        # Swift concepts
        This is a simple hello world program written in Swift:
        ```swift
        print("Hello, world!")
        ```

        ## Functions
        `print` is a function accepting an argument. Create your own functions using the `func` keyword:
        ```swift
        func say(_ message: String, to person: String) {
            print("\(message), \(person)!")
        }

        // Call the function
        say("Hello", to: "Peter") // Hello, Peter!
        ```
        > Additional information:
        > Dont understand the code, or interested in learning more about a topic?
        > The additional information block is available at the end of every section.
        > - [Functions](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/functions)
        > - [The Basics](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics)
        > - [Strings and Characters](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/stringsandcharacters)

        ## Structures
        As one can see in the example, Swift provides the basic data type `String` for text.
        There are different groups of types in Swift.
        The most often used ones, especially with _Adwaita for Swift_, are structures:
        ```swift
        struct Rectangle {

            var width: Int
            var height: Int

            var area: Int {
                width * height
            }

        }

        // Create an instance
        let rectangle = Rectangle(width: 30, height: 20)
        print(rectangle.area) // 600
        ```

        In this code snippet, there is a number of new patterns:
        - `let rectangle = Rectangle(width: 30, height: 20)` assigns a value of the type `Rectangle` to a constant. The constant can be called by its name `rectangle` after the declaration.
        - `width` is a stored property of the type `Int`, the basic data type for integers, on the structure `Rectangle`. As the name suggests, it stores a value on an instance of the type.
        - `area` on the other hand is a computed property. It is a property that is calculated when it gets called instead of storing a value.
        - Call a property using the syntax `instance.property`.

        > Additional information:
        > - [The Basics](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics)
        > - [Basic Operators](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/basicoperators)
        > - [Structures and Classes](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/classesandstructures)
        > - [Functions](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/functions)
        > - [Properties](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties)
        > - [Initialization](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/initialization)

        ## Methods
        Methods are functions that are defined on top of types, most importantly structures.
        ```swift
        struct Cat {

            var name: String

            func hasName(_ name: String) -> Bool {
                self.name == name
            }

            mutating func rename(to newName: String) {
                name = newName
            }

        }

        // Create an instance
        print(Cat(name: "Fred").hasName("Bob")) // false

        // Save an instance to a variable
        var cat = Cat(name: "Steve")
        cat.rename(to: "Peter")
        print(cat.name) // Peter
        ```

        In this code snippet, there are the following new patterns:
        - `var cat = Cat(name: "Steve")` assigns a value of the type `Cat` to a variable. The constant can be called _and modified_ by its name `cat` after the declaration.
        - A method definition starting with `mutating` can modify the properties while it runs. Nonmutating functions normally return a value, similar to computed properties, they cannot change the instance.
        - Call a method using the syntax `instance.method()`, and specify parameters if necessary.
        - As you saw before, you can access properties (and also methods) from within a type directly by its name. `self` refers to the instance it runs on, so `self.name` also calls the property `name`.

        > Additional information:
        > - [Methods](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/methods)
        > - [The Basics](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics)
        > - [Strings and Characters](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/stringsandcharacters)
        > - [Functions](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/functions)
        > - [Structures and Classes](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/classesandstructures)
        > - [Properties](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties)
        > - [Initialization](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/initialization)

        ## Modifiers
        Modifiers are special methods that, instead of mutating an instance, create a copy of an instance, modify the copy and return the copy.
        ```swift
        struct Box {

            var isOpen = false

            func open(_ isOpen: Bool = true) -> Self {
                var newSelf = self
                newSelf.isOpen = isOpen
                return newSelf
            }

        }

        // Save an instance to a variable
        var box = Box().open().open(false).open()
        print(box.isOpen) // false
        ```

        The new concepts are:
        - `Self` (with a capital "S") refers to the type it is defined on (in this case `Box`).
        - In all the previous example, the `return` keyword has been omitted for returning values because Swift allows this for bodies with a single line only. As this function's body spans multiple lines, the `return` keyword is required.

        > Additional information:
        > - [The Basics](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics)
        > - [Functions](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/functions)
        > - [Structures and Classes](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/classesandstructures)
        > - [Properties](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties)
        > - [Methods](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/methods)
        > - [Initialization](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/initialization)

        ## Closures
        You cannot only pass values as parameters, but also functions. This can be done using a special syntax called closure expression syntax.
        ```swift
        func run(function: () -> Void) {
            function()
        }

        // Call the run function
        run {
            print("Hello, world!")
        } // Hello, world!
        ```

        `() -> Void` is the type of a function that accepts no argument (`()`) and returns nothing (`Void`).

        It's also possible to use parameters within closures, and return a value:
        ```swift
        func modifyAndPrint(string: String, modify: (String) -> String) {
            print(modify(string))
        }

        // Call the modifyAndPrint function
        modifyAndPrint(string: "Hello") { string in
            "\(string), world!"
        } // Hello, world!
        ```

        > Additional information:
        > - [Closures](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures)
        > - [The Basics](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics)
        > - [Strings and Characters](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/stringsandcharacters)
        > - [Functions](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/functions)

        ## Protocols
        A protocol is a type that defines requirements for structures and other types.
        It cannot be initialized itself, but implemented by other types.
        ```swift
        protocol Named {

            var name: String { get }

        }

        // Adopt the protocol by a structure
        struct Cat: Named {

            // This property is required to conform to the protocol (it can be stored or computed)
            var name: String

        }

        let namedSpecies: Named = Cat(name: "Bob")
        print(namedSpecies.name) // Bob
        ```

        `var name: String { get }` defines that the property `name` must be available. If it were `var name: String { get set }`, a constant or simple computed variable wouldn't work since the property has to be mutable.

        You can see that a type cannot only be specified explicitly for properties, but for any variable or constant. Without the `: Named`, the type of `namedSpecies` would be `Cat`.
        Setting the type to `Named` allows it to take a value of any type conforming to the `Named` protocol.

        > Additional information:
        > - [Protocols](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/protocols)
        > - [The Basics](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics)
        > - [Strings and Characters](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/stringsandcharacters)
        > - [Structures and Classes](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/classesandstructures)
        > - [Properties](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties)
        > - [Initialization](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/initialization)
        > - [Opaque and Boxed Types](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/opaquetypes)

        ## Property wrappers
        A property wrapper is a structure that is designed to wrap a property, meaning that it controls how a property is stored.
        ```swift
        @propertyWrapper
        struct Percentage {

            private var number = 0

            var wrappedValue: Int {
                get {
                    number
                }
                set {
                    if newValue >= 0 && newValue <= 100 {
                        number = newValue
                    }
                }
            }

        }

        struct Transportation {

            // Use the property wrapper
            @Percentage var train: Int

        }

        var transportation = Transportation()
        transportation.train = 63
        print(transportation.train) // 63
        transportation.train = 104
        print(transportation.train) // 63
        ```

        In this code example, you can see different new concepts:
        - `private` determines that `number` is not visible outside the structure.
        - The computed property `wrappedValue` contains a getter and a setter. So far, we have seen computed variables with a getter only. The setter handles assignments with `=`, as you have seen for stored properties already.
        - Use a property wrapper by adding the @ symbol to the beginning of the struct's name.
    }

}
