swift - eecs.wsu.eduholder/courses/mad/slides/02-swift.pdf · why swift • recommended for all...

26
Swift Mobile Application Development in iOS School of EECS Washington State University Instructor: Larry Holder Mobile Application Development in iOS 1

Upload: doankiet

Post on 26-Sep-2018

223 views

Category:

Documents


0 download

TRANSCRIPT

SwiftMobile Application Development in iOS

School of EECS

Washington State University

Instructor: Larry Holder

Mobile Application Development in iOS 1

Why Swift

• Recommended for all iOS, macOS, watchOS, and tvOS

app development

• Designed by Apple, but now open source

• Available for Windows and Linux too

• Faster than Python, and C++ in some cases

– Can directly call C/C++ code

• Swift vs. Python, C++, Java, Go, …

Mobile Application Development in iOS 2

Xcode Playgrounds• Blank

• Game

• Map

• Single View

Mobile Application Development in iOS 3

Good Tutorials• The Swift Programming Language (Swift 4)

– developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language

– The Swift Tour

– Includes Playground for all code

• Ray Wenderlich

– http://raywenderlich.com/category/swift

Mobile Application Development in iOS 4

Caveat

• Assume proficiency in some object-oriented

language (e.g., C++, Java, Python)

Mobile Application Development in iOS 5

Constants, Variables & Types

• Constants (let) vs. variables (var)

• Types (convention: first letter capitalized)

– Basic types: Bool, Int, Float, Double, String

– Collection types: Array, Set, Dictionary

– Tuples

Mobile Application Development in iOS 6

var shoppingList = ["coffee": 3, "candy": 4]for (item, amount) in shoppingList {

print("\(item): \(amount)")}

Optionals

• Optional variable can be nil or hold a value

• Optional binding

Mobile Application Development in iOS 7

let possibleStr: String? = "Hello" // optional typeprint(possibleStr) // outputs "Optional("Hello")”, warninglet forcedStr: String = possibleStr! // unwrappingprint(forcedStr) // outputs "Hello"let assumedStr: String! = "Hello" // implicitly unwrappedlet implicitStr: String = assumedStr // no need for !

if let tempStr = possibleStr {print(tempStr)

}

Range Operators

• Range operators (a…b, a..<b)

Mobile Application Development in iOS 8

let count = 5for index in 1...count {

print("\(index)") // 1 2 3 4 5}

for index in 0..<count {print("\(index)") // 0 1 2 3 4

}

Functions

Mobile Application Development in iOS 9

func fahrenheitToCelsius (temp: Float) -> Float {let tempC = (temp - 32.0) * 5.0 / 9.0return tempC

}

func printCelsius (temp tempF: Float) {let tempC = fahrenheitToCelsius(temp: tempF)print("\(tempF) F = \(tempC) C")

}

func printF2CTable (_ low: Int = 0, _ high: Int = 100) {for temp in low...high {

printCelsius(temp: Float(temp))}

}printF2CTable()printF2CTable(70)printF2CTable(70,80)

Function Types

Mobile Application Development in iOS 10

func addTwoInts (_ a: Int, _ b: Int) -> Int {return a + b

}

var mathFunction: (Int, Int) -> Int = addTwoInts

print("Result: \(mathFunction(2, 3))") // prints “Result: 5”

func printMathResult (_ mathFunction: (Int, Int) -> Int,_ a: Int, _ b: Int) {

print("Result: \(mathFunction(a, b))")}

printMathResult(addTwoInts, 3, 5) // prints “Result: 8”

Closures

• Self-contained block of code

• Can capture references to variables in context

• General form:

Mobile Application Development in iOS 11

{ (parameters) -> return-type instatements

}

Closures (cont.)

Mobile Application Development in iOS 12

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

func backward(_ s1: String, _ s2: String) -> Bool {return s1 > s2

}

var reversedNames = names.sorted (by: backward)

reversedNames = names.sorted (by: { (s1: String, s2: String) -> Bool inreturn s1 > s2

})

Closures: Capturing Values

Mobile Application Development in iOS 13

func makeIncrementer(forIncrement amount: Int) -> () -> Int {var runningTotal = 0func incrementer() -> Int {

runningTotal += amountreturn runningTotal

}return incrementer

}

let incrementByTen = makeIncrementer(forIncrement: 10)

incrementByTen() // returns a value of 10incrementByTen() // returns a value of 20incrementByTen() // returns a value of 30

Escaping Closures• Closure passed to function, but called after function returns

Mobile Application Development in iOS 14

var completionHandlers: [() -> Void] = []

func addCompletionHandler (handler: @escaping () -> Void) {completionHandlers.append(handler)

}

func printHello() {print("Hello")

}

addCompletionHandler(handler: printHello)for handler in completionHandlers {

handler()}

Enumerations

Mobile Application Development in iOS 15

enum Direction {case up // does not imply .up = 0case leftcase downcase right

}

var playerDirection = Direction.rightplayerDirection = .up // type inference

func turnLeft (direction: Direction) -> Direction {var newDirection: Directionswitch direction {

case .up: newDirection = .left // no breakcase .left: newDirection = .downcase .down: newDirection = .rightcase .right: newDirection = .up

}return newDirection

}

Enumerations (cont.)

• Raw values

Mobile Application Development in iOS 16

func facingLeftOrRight (direction: Direction) -> Bool {switch direction {

case .left, .right: return truedefault: return false

}}

enum Direction: Int {case up = 0, left, down, right // now they’re Int’s

}Direction.left.rawValue // equals 1

enum Direction: String {case up, left, down, right // now they’re String’s

}Direction.left.rawValue // equals “left”

Classes

Mobile Application Development in iOS 17

class Player {var direction: Directionvar speed: Floatvar inventory: [String]? // initialized to nil

// init required to set uninitialized variablesinit (speed: Float, direction: Direction) {

self.speed = speedself.direction = direction

}

func energize() {speed += 1.0

}}

var player = Player(speed: 1.0, direction: .right)

Classes (cont.)

Mobile Application Development in iOS 18

class FlyingPlayer : Player {var altitude: Float

init (speed: Float, direction: Direction, altitude: Float) {self.altitude = altitudesuper.init (speed: speed, direction: direction)

}

override func energize() {super.energize()altitude += 1.0

}}

var flyingPlayer = FlyingPlayer(speed: 1.0, direction: .right, altitude: 1.0)

Must initialize all non-optional child properties before initializing parent.

Class vs. Struct

• Classes passed by reference

• Structs passed by value

Mobile Application Development in iOS 19

class Foo1 {var x : Int = 1

}func changeX (foo : Foo1) {

foo.x = 2}

var foo1 = Foo1()changeX(foo: foo1)foo1.x // equals 2

struct Foo2 {var x : Int = 1

}

func changeX (foo: Foo2) {foo.x = 2 // errorvar tmpFoo: Foo2 = footmpFoo.x = 2

}

var foo2 = Foo2()changeX(foo: foo2)foo2.x // equals 1

Optional Chaining

Mobile Application Development in iOS 20

var myPlayer = Player(speed: 1.0, direction: .right)

let firstItem = myPlayer.inventory.first // errorlet firstItem = myPlayer.inventory!.first// errorlet firstItem = myPlayer.inventory?.first// nil (OC)myPlayer.inventory?.append("potion") // nil (OC: no effect)type(of: firstItem) // Optional<String>

if let item = myPlayer.inventory?.first {print("item = \(item)") // nothing printed (OC)

}

myPlayer.inventory = [] // array initializedmyPlayer.inventory?.append("potion") // “potion” addedlet item = myPlayer.inventory?.first // “potion”

if let item = myPlayer.inventory?.first {print("item = \(item)") // “item = potion”

}

Error Handling

• Do-try-throw-catch error handling

Mobile Application Development in iOS 21

enum myError : Error {case goodcase badcase fatal

}

func throwsError () throws {throw myError.fatal

}

func testError () {do {

try throwsError()print("no error")

} catch myError.fatal {print("fatal")

} catch {print("good or bad")

}}

Error Handling• try?: returns nil if error thrown

• try!: assumes no error thrown (or exec error)

• guard <condition> else {throw or return}

– Preferred to: if not <condition> {throw or return}

Mobile Application Development in iOS 22

if let result = try? throwsError() {print("no error: result = \(result)")

}let forcedResult = try! throwsError()guard (amount > 0) else {

throw myError.bad}

Type Casting• Regular type casting

• Downcasting (as?, as!)

Mobile Application Development in iOS 23

let x = 10 let xstr = String(x) // “10”, xstr of type Stringlet xstr2 = "\(x)" // “10” let ystr = "100"let y = Int(ystr) // 100, y of type Optional<Int>var arrayOfAnything: [Any]var arrayOfAnyClassInstances: [AnyObject]

var playerArray = [Player]()playerArray.append(flyingPlayer)playerArray.append(player)var fp : FlyingPlayer!fp = playerArray[0] as? FlyingPlayer // fp = flyingPlayerfp = playerArray[1] as? FlyingPlayer // fp = nilfp = playerArray[1] as! FlyingPlayer // error

Protocols

• Required properties and methods

• Adopted by class, struct or enum type

• Said to “conform” to protocol

Mobile Application Development in iOS 24

protocol MyFunProtocol {func isFun() -> Bool

}

class MyFunClass: MyFunProtocol {func isFun() -> Bool {

return true}

}

Delegation• Use protocols so class can delegate to others

Mobile Application Development in iOS 25

protocol MyFunDelegate {func isFun() -> Bool

}

class MyFunDelegateClass: MyFunDelegate {func isFun() -> Bool {

return true}

}

class MyFunClass {var delegate: MyFunDelegate?

func fun() -> Bool {return delegate!.isFun()

}}

var myFunClass = MyFunClass()var myFunClassDelegate = MyFunDelegateClass()myFunClass.delegate = myFunClassDelegatemyFunClass.fun() // returns true

Resources

• Swift

– swift.org

– developer.apple.com/swift

– www.raywenderlich.com/category/swift

Mobile Application Development in iOS 26