1/70

Lecture Mobile Application Development (119310)

iOS Development - Swift Fundamentals

2/70

Agenda

3/70

Objective-C

  • Developed by Brad Cox and Tom Love in the early 80s (StepStone)
  • Object oriented extension to ANSI C
  • Strict superset of C
    • Can be mixed with C and C++
  • Dynamic runtime
  • Loosely typed (if you want it)
  • Inspired by Smalltalk
  • Goal: “As fast as C but as beautiful as Smalltalk”
center 40%

83%

4/70

History of Objective-C

  • Steve Jobs licensed Objective-C in 1988
  • AppKit and Foundation were developed
  • Development base for NeXTStep UI
  • Development Tools Projekt Builder and Interface Builder
5/70

Well known Objective-C Projects

6/70

Well known Objective-C Projects

  • Tim Berners Lee: First Web-Server & Web-Browser (1990)
  • John Carmack: Doom and predecessor Wolfenstein 3D
  • Project Builder and Interface Builder are the basis of Xcode
  • NeXTStep and OpenStep are the basis of MacOS X and iOS
  • iWork (Keynote, Numbers, Pages)
7/70

Objective-C

8/70

Objective-C Example

center

9/70

Objective-C Files

Extension Source Type
.h Header files. Header files contain class, type, function, and constant declarations.
.m Source files. This is the typical extension used for source files and can contain both Objective-C and C code.
.mm Source files. A source file with this extension can contain C++ code in addition to Objective-C and C code. This extension should be used only if you actually refer to C++ classes or features from your Objective-C code.
10/70

Class Interface

@interface MyClass : NSObject
{
    int         count;
    id          data;
    NSString*   name;
}
- (id)initWithString:(NSString*)aName;
+ (MyClass*)createMyClassWithString:(NSString*)aName //Class method;
@end
11/70

Class Interface

@implementation MyClass

- (id)initWithString:(NSString *)aName
{
    self = [super init];
    if (self) {
        name = [aName copy];
    }
    return self;
}

+ (MyClass *)createMyClassWithString: (NSString *)aName
{
    return [[self alloc] initWithString:aName] ;
}
@end
12/70

NSObject

13/70

Using a class

//create an Object of SomeClass:
id anObject = [[SomeClass alloc] init]; 

//Example init method implementation in NSObject: 
- (id)init {
    
    self = [super init];
    if (self) {
        //initialisation of Object
    }

    return self;
}
14/70

Using Objects

NSString* text1 = [[NSString alloc] initWithCString: "Hello World!" encoding: NSUTF8StringEncoding];

NSString* text2 = @"Hello World!"; //short for upper statement
NSLog(@"text 1 = %@", text1); //%@ placeholder for objects
NSLog(@"text 2 = %@", text2);
        
NSLog(@"text2.length = %ld", text2.length);
15/70

Methods

center 60%

Source:Stackoverflow

16/70

Methods

 [myArray insertObject:anObject atIndex:0];
17/70

Messaging Terminology

18/70

Object Messaging Examples

[[myAppObject theArray] insertObject: [myAppObject objectToInsert] atIndex: 0];
19/70

Object Messaging Examples

// message without argument
[receiver message];

// message with single argument
[receiver message: argument];

// message with multiple arguments
[receiver message: arg1 argument2: arg2];

// receiving a return value
int status = [receiver message];

// message with a variable number of arguments
[receiver makeGroup: group, memberOne, memberTwo, memberThree];

20/70

Object Messaging Examples

// nil is essentially the same as NULL
  
NSMutableArray *myArray = nil;      

// Create a new array and assign it to the myArray variable.
    
myArray = [NSMutableArray array];

21/70

Dynamic Typing

 Person* myPerson;  // Strong typing
    
 id myObject;  // Weak typing
22/70

Dynamic Binding

//Dynamic binding example
@interface ClassA : NSObject {…}
- (void) doSomething;
@end

@interface ClassB : NSObject { …}
- (void) doSomething;
@end

// anywhere
id object = … // An object of an arbitrary class
[object doSomething]; // polymorph between ClassA und ClassB
23/70

Objective-C

NSString *helloWorld = @"Hello World";
NSLog(@"%@", helloWorld);
24/70

Swift

var str = "Hello World"
print(str)
25/70

Swift Language Goals

26/70

Whats New?

27/70

Swift Language Fundamentals

28/70

Variables

var myvariable = 0
var myvariable: Int = 0
29/70

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"

30/70

Constants

let myconstant = 10
var myvariable = 0, yourvar = 1, anothervar = 3
31/70

Optionals

var rabbit: String? //declares optional String
... //rabbit = "running"
if (rabbit != nil){
    print("Rabbit is \(rabbit!)") //unwraps Optional
} else {
    print("Rabbit is nil")
}
32/70

Enumerations

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")
}
33/70

Basic Data Types

34/70

Int

var smallInt: UInt8 = 5
var largertInt: Int16 = 10
var evenLargerInt: Int32 = 100
var biggestInt: UInt64 = 1000
UInt8.min //0
UInt8.max //255
Int16.min // -32768
Int16.max // 32768
35/70

Float, Double

var mySmallFloat: Float = 2.34352
var myBigFloat: Double = 3.42323
let pi = 3 + 0.14159
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
36/70

Boolean

let hdmIsGreat = true
let swiftIsBoring = false
let i = 1
if i {
    //will not compile and report an error
}
let i = 1
if i==1 {
    //this works
}
37/70

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.

38/70

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!"
39/70

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“
40/70

Strings & Characters

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

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

Use count() to count Chars

string.characters.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.characters.indices[range] {
    print("\(string[mindex])",terminator: "")
}
41/70

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!"
42/70

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. Example: Scientific Swift

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

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)")
	}
}

44/70

Arrays

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"]
45/70

Arrays

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)
46/70

Arrays

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"]
47/70

Tuples

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)")
48/70

Control Flow

49/70

For-In-Loop

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)")
}
50/70

For-Loop

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

51/70

While

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
52/70

If

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."
53/70

Switch

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")
}
54/70

Switch With Tuple

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"
55/70

Swift Assignment

56/70

Functions & Closures

func greet(name: String, day: String) -> String {
    return "Hello \(name), today is \(day)."
}
greet(name: "Bob", day: "Tuesday")
57/70

Functions & Closures

func greet(name: String, day d: String) -> String {
    return "Hello \(name), today is \(d)."
}
greet(name: “Bob", day: "Tuesday")
58/70

Functions & Closures

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)
59/70

Functions & Closures

func returnFifteen() -> Int {
	var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
returnFifteen()
60/70

Functions & Closures

func makeIncrementer() -> ((Int) -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)
61/70

Functions & Closures

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)
62/70

Functions & Closures

var numbers = [20, 19, 7, 12]
numbers.map({
    (number: Int) -> Int in
    let result = 3 * number
    return result
})
63/70

Classes

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
64/70

Classes

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
let myShape = Shape()
myShape.numberOfSides = 10
myShape.simpleDescription()
65/70

Classes

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")
66/70

Assert

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
67/70

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()
68/70

Protocol Extensions

//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)")
69/70

Swift is OpenSource

70/70

References