Open menu with table of contents iOS Development - Swift Fundamentals
Logo of Stuttgart Media University for light theme Logo of Stuttgart Media University for dark theme
Mobile Application Development 2

iOS Development - Swift Fundamentals

Stuttgart Media University

1 Agenda

  • Swift Basics
  • Swift Exercise

2 Swift Language Goals

  • Easy to use, like a scripting language (Python, JS)
  • Powerful functional approach
  • Fully object oriented
  • Completely compatible with Objective-C (and C)
  • Designed to avoid programming mistakes

3 Whats New?

  • Following language concepts are new compared to Objective-C and borrowed from different languages:
    • Optionals (optional return values, similar to python)
    • Closures (similar to Block Objects or closures in Lisp, C#)
    • Tuples (similar to multiple returns in python)
    • Generics (similar to Java Generics or C++ Templates)
    • Type Inference (similar to JavaScript) -> But: Swift is a type safe language

4 Swift Language Fundamentals

  • Variables and Constants
  • Optionals
  • Basic Data Types
  • Control Flows
  • Functions & Closures
  • Classes
  • Exception Handling with Try / Catch & Guard
  • Protocol Extensions

More background information: Swift Language History

Learn Swift: Swift Language Guide

5 Variables

  • Variables are declared using the keyword var
var myvariable = 0
  • Variables are strongly typed
  • If type is not explicitly defined, it is inferred automatically when a value is assigned
  • Type annotation can be used to define the type explicitly:
var myvariable: Int = 0

6 Variables

var name = "Name" // Type is inferred as String

var age = 38 // Type is inferred as Int

var weight = 90.5 // Type is inferred as Double

var myvariable: Int // Type annotation defining type Int

var myName: String = "HdM"

7 Constants

  • Constants are declared using the keyword let
let myconstant = 10
  • They must be initialized (at some time, before usage)
  • Are guaranteed to always retain the value they were first assigned
  • They can not be changed once they are set
  • Multiple constants or variables can be declared in one line separating them with commas:
var myvariable = 0, yourvar = 1, anothervar = 3

8 Optionals

  • Qualifier for a variable (own data type)
  • Indicates the variable may not have a value set
  • If non-optional, no null (or nil in swift) values can be set
  • Use a ? after the Type to declare it as optional
  • Use a ! to "unwrap" the optional and retrieve the contained object
var rabbit: String? //declares optional String
... //rabbit = "running"
if (rabbit != nil){
    print("Rabbit is \(rabbit!)") //unwraps Optional
} else {
    print("Rabbit is nil")
}

9 Basic Data Types

  • Integer
  • Float & Double
  • Boolean
  • Strings & Characters
  • Arrays
  • Tuples

10 Int

  • Swift provides signed and unsigned integers in 8,16,32 and 64 bit forms
var smallInt: UInt8 = 5
var largertInt: Int16 = 10
var evenLargerInt: Int32 = 100
var biggestInt: UInt64 = 1000
  • To access the minimum and maximum values of each integer type they provide min and max properties
UInt8.min //0
UInt8.max //255
Int16.min // -32768
Int16.max // 32768
  • On a 32-bit platform, Int is the same size as Int32 on 64-bit it is the size of Int64 (same is true for UInt)

11 Float, Double

  • Floating point number are either Float (32-bit) or Double (64-bit)
var mySmallFloat: Float = 2.34352
var myBigFloat: Double = 3.42323
  • When inferring the type of a floating-point number, Swift alway chooses Double
  • When combining integer and float, Double is also inferred
let pi = 3 + 0.14159
  • To make reading numbers more easy, numeric literals can be padded with extra zeros or contain underscores
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1

12 Boolean

  • Swift has a basic Boolean type called Bool
let hdmIsGreat = true
let swiftIsBoring = false
  • In contrast to C or Objective-C, non-boolean values can not be substituted for Bool. This would not work:
let i = 1
if i {
    //will not compile and report an error
}
  • An alternative would be
let i = 1
if i == 1 {
    //this works
}

13 Range

A Range or CountableRange (since Swift 3.0) is a type in Swift that defines a number of elements that can be iterated over, e.g. a number of integer values or String.Index values The Range can be created using the range operator: ClosedRange operator: ... Range operator: ..<

let myFromZeroTo5Range = 0...5 //CountableClosedRange(0...5)
let myFromZeroToSmallerSixRange = 0..<6 //CountableRange(0..<6))

Since Swift 3.0 ClosedRange (...) and Range (..<) are two different types which can not be converted into each other.

14 Strings & Characters

Swift Strings and Characters are value types, Unicode compliant and easy to use

let emptyImmutableString = ""
var emptyMutableString = ""
var emptyString = String()
let sparklingHeart = "\u{1F496}"

String values can be constructed by passing an array of Characters

let catCharacters: [Character] = ["C", "a", "t", "!", "🐱"]
let catString = String(catCharacters)

Concatenation of Strings and Characters is simple

let string1 = "Hello "
let string2 = "HdM"
let char1: Character = "!"

var concatenatedString = string1 + string2 //"Hello HdM"
concatenatedString.append(char1) // "Hello HdM!"

15 Strings & Characters

String interpolation allows to create a new String from multiple variables or literals

let multiplier = 3
let message = "\(multiplier) times 2 is \(multiplier*2)" //„3 times 2 is 6“

Expressions in the parentheses cannot contain double quotes, backslashes, a carriage return or line feed You can call functions within the parentheses

func getHint() -> String {
    return "special hint"
}
let newmessage = "New hint: \(getHint())" //„New hint: special hint“

16 Strings & Characters

The property „characters“ allows you to iterate over all characters in a String

for letter in string {
    print("\(letter)")
}

Use count() to count Chars

string.count // 19

Use can create a range to access Characters of a part of a String

let range = string.index(string.startIndex, offsetBy: 5)..<string.index(before: string.endIndex)

for mindex in string.indices[range] {
    print("\(string[mindex])",terminator: "1")
}

17 Strings & Characters

To modify strings, you can use insert(), remove() and removeSubrange()

var myString = "Hello HdM"

var idx = myString.index(myString.endIndex, offsetBy: -2) //7

myString.remove(at: idx) // „Hello HM“

let r = myString.index(myString.startIndex, offsetBy: 5)..<myString.endIndex

myString.removeSubrange(r) // „Hello“

myString.insert("!", at: myString.endIndex) //"Hello HM!"

18 Strings & Characters

String and Character equality is checked using the „equal to“ operator (==) Strings are equal if they have the same linguistic meaning and appearance, even if they are composed from different Unicode scalars

let eAcuteQuestion = "Voulez-vous un caf\u{E9}?"
let combinedEAcuteQuestion = "Voulez-vous un caf\u{65}\u{301}?"
if eAcuteQuestion == combinedEAcuteQuestion {
    print("\(eAcuteQuestion) and \(combinedEAcuteQuestion) are considered equal")
}
// "Voulez-vous un café? and Voulez-vous un café? are considered equal"

Further you can use fully unicode.

let β = 3 * t - r * sin(φ) * cos(θ)

19 Strings & Characters

You can check the prefix or suffix of a String using hasPrefix() and hasSuffix()

let stringArray = ["1st String of 2","2nd String of 2"]

for string in stringArray {
    if string.hasPrefix("1st") {
        print("String starting with 1st: \(string)")
    }

    if string.hasSuffix("2") {
        print("String ending with 2: \(string)")
    }
}

20 Enumerations

  • An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code
enum GraphicalObjects {
    case Circle
    case Rectangle
    case Polygon
}

var go = GraphicalObjects.Circle

if go == GraphicalObjects.Circle {
    print("is a Circle")
} else if go == .Rectangle {
    print("is a Rectangle")
} else {
    print("is a Polygon")
}

21 Arrays - Introduction

Arrays are next to sets and dictionaries the mostly used collections in swift To create a mutable array, assign it to a variable (e.g. var myArray)

var shoppingList = [String]()

Initialize directly by writing:

var shoppingList = ["Apples", "Pears", "Bread", "Milk"]

22 Arrays - Appending items

Appending items to an Array

shoppingList.append("Soap")
//or
shoppingList += ["Juice"]

Adding Arrays and creating new ones

var familyList = shoppingList + ["Cornflakes","Ice Cream"]

Removing items from an Array

shoppingList.remove(at: 2)
shoppingList.removeLast()
shoppingList.removeAll(keepingCapacity: true)

23 Arrays - Check if empty

Check if an Array is empty

if shoppingList.isEmpty {
    ...
}

Retrieve a certain item or a part of the Array

shoppingList[5] //-> "Cornflakes"
shoppingList[1...3] //["Pears", "Bread", "Milk"]

24 Tuples - Introduction

Tuples group multiple values into a single compound value

let httpStatus = (404, "Not Found")

Each single value is accessible by a number, e.g.:

httpStatus.0 // 404
httpStatus.1 // "Not Found"

Tuples can be decomposed into their separate values

let (statusCode, description) = httpStatus
print("Statuscode: \(statusCode) means: \(description)")

You can name the elements in a tuple and access them using the names

let newHttpStatus = (code: 200, description: "OK")
print("code: \(newHttpStatus.code)")
print("description: \(newHttpStatus.description)")

25 Control Flow - Introduction

  • Loops: for, while, repeat-while
  • Conditional statements: if, switch, where, assert

26 For-In-Loop - Iterating over an Array

Iterating over an Array

var familyList = ["Milk", "Bread","Soap","Juice"]
for item in familyList {
    print(item)
}

Iterating with index and value

for (index,value) in familyList.enumerated() {
    print("item nbr. \(index + 1) is: \(value)")
}

27 For-Loop - Iterating over a range

Since Swift 3.0 for-loops look like this:

for index in 0 ..< 3 {
    print("index is \(index)")
}

C-style loops are not supported anymore

28 While-Loop - Introduction

Use the while loop to iterate while a condition is true

var shoppingList = ["Apples","Pears","Bread","Milk"]
while !shoppingList.isEmpty {
    print("remove one item from list")
    shoppingList.removeLast()
}

Use do-while to test the condition after executing the statements

shoppingList = ["Apples","Pears","Bread","Milk"]
repeat {
    shoppingList.removeLast()
} while !shoppingList.isEmpty

29 If-Statement - Introduction

Test a condition using if The else-if and final else clause is optional

var temperatureInFahrenheit = 90
if temperatureInFahrenheit <= 32 {
    print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
    print("It's really warm. Don't forget to wear sunscreen.")
} else {
    print("It's not that cold. Wear a t-shirt.")
}
// prints "It's really warm. Don't forget to wear sunscreen."

30 Switch-Statement - Introduction

  • Use switch to compare a value against several possible matching patterns
  • In contrast to C and Objective-C the entire switch statement finishes its execution as soon as the first matching switch case is completed (no fall-through to other cases)
    • Break statement is not required but can still be used
let someCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
    print("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
    print("\(someCharacter) is a consonant")
default:
    print("\(someCharacter) is not a vowel or a consonant")
}

31 Switch With Tuple

  • A switch case can use a where clause to check for additional conditions
  • In the following example, a Tuple representing a Point in a coordinate system is checked using a switch statement
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
    print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
    print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
    print("(\(x), \(y)) is just some arbitrary point")
}
// prints "(1, -1) is on the line x == -y"

32 Hands On Swift - Part 1

Exercise

33 Functions & Closures - Introduction

  • To declare a function use the keyword func. To call a function using the name followed by the parameters in parentheses
  • The parameters alway are defined with a name followed by a colon and the type.
  • The return value is declared after the ->
  • See chapter on Functions in the Swift documentation
func greet(name: String, day: String) -> String {
    return "Hello \(name), today is \(day)."
}
greet(name: "Bob", day: "Tuesday")

34 Functions & Closures - Parameters

  • Parameters of a function can have a name and a description. The description (day) is obligatory and the name (d) is optional. If no name is given, the description is automatically used as name for the parameter
  • Within the function the parameter is referenced by the name
func greet(name: String, day d: String) -> String {
    return "Hello \(name), today is \(d)."
}
greet(name: “Bob", day: "Tuesday")

35 Functions & Closures - Returning multiple values

It is possible to return multiple values from a function using Tuples

func getGasPrices() -> (Double, Double, Double) {
    return (3.59, 3.69, 3.79)
}
getGasPrices()

Functions can take a variable number of arguments

func sumOf(numbers: Int...) -> Int {
    var sum = 0
       for number in numbers {
        sum += number
       }
    return sum
}
sumOf()
sumOf(numbers: 42, 597, 12)

36 Functions & Closures - Nested functions

  • Functions can be nested
func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
returnFifteen()

37 Functions & Closures - Returning functions

  • Functions are first class types and can be returned as a value
func makeIncrementer() -> ((Int) -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

38 Functions & Closures - Passing functions as parameters

  • Functions can take other functions as a parameter
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}

func lessThanTen(number: Int) -> Bool {
    return number < 10
}

var numbers = [20, 19, 7, 12]
hasAnyMatches(list: numbers,condition: lessThanTen)

39 Functions & Closures - Closures

  • Closures are functions without a name surrounded by braces
  • The keyword in is used to separate arguments and return type from the body of the closure
var numbers = [20, 19, 7, 12]
numbers.map({
    (number: Int) -> Int in
    let result = 3 * number
    return result
})

40 Structs & Classes - Introduction

  • Structures and classes are general-purpose, flexible constructs that become the building blocks of your program’s code.
  • You can properties and methods using the same syntax you use to define constants, variables, and functions.
  • Structs are very similar to Classes, but lack certain capabilities, e.g. inheritance and type casting
struct Resolution {
    var width = 0
    var height = 0
}

// create an instance

let someResolution = Resolution()

41 Structs & Classes - Introduction

  • A Class is defined using the keyword class
class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

42 Classes - definition

  • A Class is defined using the keyword class
class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
  • An instance is created by putting parentheses after the class name
let myShape = Shape()
myShape.numberOfSides = 10
myShape.simpleDescription()

43 Classes - Initializer

  • A Class should always have an initializer (Java: Constructor)
  • To create an initializer use the keyword init
class NamedShape {
    var numberOfSides: Int = 0
    var name: String

    init(name: String) {
        self.name = name
    }

    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

let s = NamedShape(name: "MyShape")

44 Properties - Introduction

  • Properties in Swift are like member variables with a getter and setter method in Java
  • Swift Properties combine Objective-C’s instance variables and properties in one
  • Properties can be constant, variable or computed

center 70%

45 Properties - Getter and Setter

  • Properties can define a getter and a setter

center 70%

46 Protocols in Swift - Introduction

  • A Protocol is in Swift what an Interface is in Java
  • It defines a number of requirements that need to be fulfilled by the implementing classes
    • Property requirements - defines Properties that need to be implemented
    • Method requirements - defines Methods that need to be implemented

47 Protocols in Swift - Definition

  • Protocols are defined very similar to classes and structures
  • To implement a Protocol in a class you declare it like this:
protocol SomeProtocol {
    // protocol definition goes here
}

class SomeClass: SomeSuperClass, FirstProtocol, SomeProtocol {
    // class definition goes here
}

48 Protocols in Swift - Property requirements

  • Property requirements are declared as variable properties and indicate if they are gettable or settable:
protocol SomeProtocol {

    // a settable Property must be implemented using
    // var in the implementing class
    var mustBeSettable: Int { get set }

    // a only gettable Property should be implented using let
    var doesNotNeedToBeSettable: Int { get }

}

49 Protocols in Swift - Method requirements

  • Method requirements are declared like this (like a normal method declaration just without curly braces and implementation):
protocol RandomNumberGenerator {

    func random() -> Double

}

50 Hands On Swift - Part 2

Exercise

51 Assertions - Introduction

  • An assertion is a runtime check that a logical condition evaluates to true
  • Assertions can be used to debug your code
  • Assertions are written by using the global assert() function
let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
// this causes the assertion to trigger, because age is not >= 0

52 Exception Handling Try / Catch & Guard

class FatherChristmas {

    enum DeliveryError : Error {
        case NoPresentsRemaining
    }

    var numberOfPresents = 0

    func deliverPresents() throws {
        guard numberOfPresents > 0 else {
            throw DeliveryError.NoPresentsRemaining
        }
        print("Presents delivered")
    }
    func itIsChristmasEve(){
        do {
            try deliverPresents()
        } catch DeliveryError.NoPresentsRemaining{
            print("Could not deliver presents!")
        } catch {
            print("Unknown error")
        }
    }

}
let fatherChristmas = FatherChristmas()
fatherChristmas.itIsChristmasEve()

53 Protocol Extensions - Introduction

  • Allows to add functionality to existing classes or protocols
//this protocol defines the "description" method used by many classes
extension CustomStringConvertible {
    var shoutyDescription: String {
        return "\(self.description.uppercased())!!!"
    }
}

let greetings = ["Hello", "Hi", "Yo yo yo"]

print("\(greetings.description)")

    // prints "["HELLO", "HI", "YO YO YO“]!!!\n"

print("\(greetings.shoutyDescription)")

54 Asynchronous Functions - Introduction

More information on asynchronous functions can be found here

55 Swift is OpenSource