quick swift tour
DESCRIPTION
Presentation slides about SwiftTRANSCRIPT
Quick Swift Tour
Swift Language
• Fast!
• Modern!
• Safe!
• Interactive
Fast• Swift code is compiled and optimised by the
advanced LLVM compiler
• ARM and x86-64 native code
• Tuned native collections
• Swift-specific optimiser
• C-like procedural performance
Modern• Clean syntax!
• No headers!
• No semicolons !
• Multiple return values!
• Optional arguments !
• Closures!
• Generics
Safe• Type safety with type inference!
• No uninitialized data!
• Array bounds checks!
• Restricts direct access to pointers!
• Automatically manages memory using ARC
Interactive• REPL
• Playgrounds
Swift Tour
• Variable and Constant!
• String!
• Array, Dictionary!
• Optionals!
• Control Flow!
• Function / Closure!
• Class!
• Enum / Struct!
• Protocol / Extension!
• Generics
Variables / Constants!// variable var myVariable = 42 myVariable = 50 !// constant let myConstant = 42 //myConstant = 1 <- compile error !!// How to specify type var age: Int = 34 let distance: Double = 2.0
String!let age = 34 let label = "Age: " !!// Values are never implicitly converted to another type. let desc1 = label + String(age) !// Simpler way with a backslash(\) let desc2 = "Age: \(age)”
Array, Dictionary!// Create arrays and dictionaries using brackets ([]) !// Array var iOSMembers = ["ichinose", "hato", "horimi", "tasaka", "watanabe"] !// Dictionary let appMember = ["ios": iOSMembers] !!// Use initializer syntax to create an empty array or dictionary var emptyArray = [String]() var emptyDict = [String: Int]()
Optionals
nil in Swift• Swift’s nil is not the same as nil in Objective-C.
In Swift, nil cannot be set to variables and constants…!var value: Int = 10 value = nil // compile error let value1: String = nil // compile error
• Objective-C:nil is a pointer to a nonexistent object.
• Swift:nil is the absence of a value.
Optionals
!var serverResponseCode: Int? = 404 // serverResponseCode contains an actual Int value of 404 !serverResponseCode = nil // serverResponseCode now contains no value !// When no default value is set, // surveyAnswer is automatically set to nil var surveyAnswer: String?
• Optionals indicate that a constant or variable is allowed to have “no value”
If Statements and Forced Unwrapping
!let optionalValue: Int? = 10 !// (==) and (!=) can be used for nil check if optionalValue != nil { // Use "!" to access underlying value of optionalValue println("optionalValue has an integer value of \(optionalValue!).") }
Implicitly Unwrapped Optional• Placing an exclamation mark (String!) rather than a question mark (String?)
• Useful when an optional value will always have a value
• No need to check and unwrap the optional’s value every time it is accessed
!let possibleString: String? = "An optional string." !// requires an exclamation mark let forcedString: String = possibleString! !!let assumedString: String! = "An implicitly unwrapped optional string." !// no need for an exclamation mark let implicitString: String = assumedString
Control Flow
for!var firstForLoop = 0 for i in 0...3 { // equal to 0..<4 firstForLoop += i } !!let interestingNumbers = [ "Prime": [2, 3, 5, 7, 11, 13], "Fibonacci": [1, 1, 2, 3, 5, 8], ] var largest = 0 // key and value can be passed for (kind, numbers) in interestingNumbers { for number in numbers { if number > largest { largest = number } } }
switch
!let value: Int = 10 switch value { case 0: println("\(value)") case 1..<3: // range comparison println("\(value)") case 4, 5: println("\(value)") default: println("\(value)") }
• Flexible matching patterns • No break • default must appear last
switch• switch are NOT limited to integers!
!let vegetable = "red pepper” !var vegetableComment: String switch vegetable { case "celery": vegetableComment = "Add some raisins and make ants on a log.” !case "cucumber", "watercress": vegetableComment = "That would make a good tea sandwich." !case let x where x.hasSuffix("pepper"): vegetableComment = "Is it a spicy \(x)?" !default: vegetableComment = "Everything tastes good in soup." }
Functions and Closures
Functions
func sayHello(personName: String) -> String { let greeting = "Hello, " + personName + "!" return greeting } !sayHello("Ameba")
Functions• Functions are first-class type.// return value func makeIncrementer() -> (Int -> Int) { func addOne(number: Int) -> Int { return 1 + number } return addOne } !// argument 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(numbers, lessThanTen)
Closures• Similar to blocks in Objective-C!
• Simple Syntax
!// Closure Expression Syntax { (parameters) -> return type in statements } !// e.g. let names = ["horimi", "ichinose", "watanabe", "hato", "tasaka"] var reversed = sorted(names, { (s1: String, s2: String) -> Bool in return s1 > s2 })
Closures
!// Inferring Type From Context reversed = sorted(names, { s1, s2 in return s1 > s2 } ) !// Implicit Returns from Single-Expression Closures reversed = sorted(names, { s1, s2 in s1 > s2 } ) !// Shorthand Argument Names reversed = sorted(names, { $0 > $1 } )
Class
Class!class NamedShape { // properties var numberOfSides: Int = 0 var name: String // initializer init(name: String) { self.name = name } // method func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." } }
Inheritance!class Square: NamedShape { var sideLength: Double ! // initializer init(sideLength: Double, name: String) { // initialize before calling super.init self.sideLength = sideLength super.init(name: name) numberOfSides = 4 } func area() -> Double { return sideLength * sideLength } // overriding super's method override func simpleDescription() -> String { return "A square with sides of length \(sideLength)." } }
getter/setter!class EquilateralTriangle: NamedShape { var sideLength: Double = 0.0 init(sideLength: Double, name: String) { self.sideLength = sideLength super.init(name: name) numberOfSides = 3 } ! // getter / setter var perimeter: Double { get { return 3.0 * sideLength } set { sideLength = newValue / 3.0 } } override func simpleDescription() -> String { return "An equilateral triangle with sides of length \(sideLength)." } }
Property Observers!class StepCounter { var totalSteps: Int = 0 { willSet(newTotalSteps) { println("About to set totalSteps to \(newTotalSteps)") } didSet { if totalSteps > oldValue { println("Added \(totalSteps - oldValue) steps") } } } } !let stepCounter = StepCounter() stepCounter.totalSteps = 200 // About to set totalSteps to 200 // Added 200 steps
Enum and Struct
Enum• Enumerations can have methods!
!enum Rank: Int { case Ace = 1 case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten case Jack, Queen, King func simpleDescription() -> String { switch self { case .Ace: return "ace" case .Jack: return "jack" case .Queen:return "queen" case .King: return "king" default: return String(self.toRaw()) } } }
Struct!struct Card { var rank: Rank var suit: Suit func simpleDescription() -> String { return "The \(rank.simpleDescription()) of \(suit.simpleDescription())" } }
• Similar to Classes!!
• Difference:!
• Class: Reference type!
• Struct: Value type
Protocols and Extensions
Protocols
!protocol ExampleProtocol { var simpleDescription: String { get } mutating func adjust() }
• In addition to classes, enumerations and structs can adopt protocols!
Protocols
struct SimpleStructure: ExampleProtocol { var simpleDescription: String = "A simple structure" mutating func adjust() { simpleDescription += " (adjusted)" } } !class SimpleClass: ExampleProtocol { var simpleDescription: String = "A very simple class." var anotherProperty: Int = 69105 func adjust() { simpleDescription += " Now 100% adjusted." } }
• mutating keyword means methods modify structure
• Class doesn’t need its methods marked as mutating keyword
Extensions• Similar to Categories in Objective-C
!extension SomeType { // new functionality to add to SomeType goes here } !extension SomeType: SomeProtocol, AnotherProtocol { // implementation of protocol requirements goes here }
Generics
!func repeat<ItemType>(item: ItemType, times: Int) -> [ItemType] { var result = [ItemType]() for i in 0..<times { result += item } return result } repeat("knock", 4)
• Generics is Template in C++
• Much of the Swift standard library is built with generic code
Wrap Up• Looking through basic Swift features
• Non Objective-C can get familiar, maybe.
• To Learn Swift, check out The Swift Programming Language. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/
Thank you!