Slide 1

Slide 1 text

Swift Denis Lebedev, iOS @ Yandex

Slide 2

Slide 2 text

Agenda • Introduction • Objective-C bridging • Good-to-know features • “Where can I Swift?”

Slide 3

Slide 3 text

Swift Chris Lattner, Swift creator

Slide 4

Slide 4 text

Swift • Multi-paradigm • Static, inferred typing • Bridged with Objective-C • No pointers

Slide 5

Slide 5 text

–Someone at WWDC Keynote It’s like “Objective-C without C.”

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Swift features • Namespacing* • Generic classes & functions • Named/default parameters • Functions are first class citizens • Optional types

Slide 8

Slide 8 text

Optionals • Used in situations where value may be absent • Alternative for obj-c nil passing • works with any type

Slide 9

Slide 9 text

Optionals - (NSInteger)indexOfObject:(id)object;

Slide 10

Slide 10 text

Optionals func indexOf(object: AnyObject) -> Int?

Slide 11

Slide 11 text

Optionals • Can be safely unwrapped (if/else) • Can be force unwrapped (runtime exception if value is missing)

Slide 12

Slide 12 text

Classes, structs, enumerations • Classes passed by reference, structs - by value • Using a struct has no runtime penalty • All scalars and even Bool are structs • Enumerations are extremely powerful

Slide 13

Slide 13 text

Enumerations enum Tree { case Empty case Leaf case Node }

Slide 14

Slide 14 text

Enumerations enum Tree { case Empty case Leaf(Int) case Node(Tree, Tree) }

Slide 15

Slide 15 text

Enumerations enum Tree { case Empty case Leaf(T) case Node(Tree, Tree) }

Slide 16

Slide 16 text

Enumerations let tree: Tree = .Node(.Leaf(1), .Leaf(1))

Slide 17

Slide 17 text

Enumerations enum Tree { case Empty case Leaf(T) case Node(Tree, Tree) ! func depth(t: Tree) -> Int { return 0 } }

Slide 18

Slide 18 text

Enumerations enum Tree { case … ! func depth() -> Int { func _depth(t: Tree) -> Int { return 0 } return _depth(self) } }

Slide 19

Slide 19 text

Enumerations enum Tree { case … ! func depth() -> Int { func _depth(t: Tree) -> Int { switch t { case .Empty: return 0 } return _depth(self) } }

Slide 20

Slide 20 text

Enumerations enum Tree { case … ! func depth() -> Int { func _depth(t: Tree) -> Int { switch t { case .Empty: return 0 case .Leaf(let _): return 1 } return _depth(self) } ! }

Slide 21

Slide 21 text

Enumerations enum Tree { case … ! func depth() -> Int { func _depth(t: Tree) -> Int { switch t { case .Empty: return 0 case .Leaf(let _): return 1 case .Node(let lhs, let rhs): return max(_depth(lhs), _depth(rhs)) } } return _depth(self) } }

Slide 22

Slide 22 text

Enumerations enum Tree { case Empty case Leaf(T) case Node(Tree, Tree) ! func depth() -> Int { func _depth(t: Tree) -> Int { switch t { case .Empty: return 0 case .Leaf(let _): return 1 case .Node(let lhs, let rhs): return max(_depth(lhs), _depth(rhs)) } } return _depth(self) } }

Slide 23

Slide 23 text

Collections • Array, Dictionary, String (contains Char) • Collections are structs • Implicitly bridged to Cocoa collection types

Slide 24

Slide 24 text

Collections func filter(…) -> Bool) -> FilterSequenceView ! func reverse(source: C) -> ReverseView Some of operations are lazy evaluated

Slide 25

Slide 25 text

Collections func filter(…) -> Bool) -> FilterSequenceView ! func reverse(source: C) -> ReverseView Some of operations are lazy evaluated

Slide 26

Slide 26 text

Built-in immutability var b = 3 b += 1 ! let a = 3 a += 1 // error

Slide 27

Slide 27 text

Dictionary immutability let d = ["key0": 0] ! d["key"] = 3 //error d.updateValue(1, forKey: "key1") //error

Slide 28

Slide 28 text

Array immutability let c = [1, 2, 3] ! c[0] = 3 // success c.append(5) // fail

Slide 29

Slide 29 text

Array immutability let c = [1, 2, 3] ! c[0] = 3 // success c.append(5) // fail It’s a bug: ! https://devforums.apple.com/message/971330#971330

Slide 30

Slide 30 text

Extensions • extends any named type (struct, enum, class) • structures code

Slide 31

Slide 31 text

Extensions struct Foo { let value : Int } ! extension Foo : Printable { var description : String { get {return "Foo"} } } ! extension Foo : Equatable { } ! func ==(lhs: Foo, rhs: Foo) -> Bool { return lhs.value == rhs.value }

Slide 32

Slide 32 text

What Swift is missing • Preprocessor • Exceptions • Access control * • KVO, KVC • Compiler attributes (platforms, deprecations, etc.) • performSelector: is unavailable

Slide 33

Slide 33 text

Objective-C bridging • Call Obj-c from Swift • Call Swift from Objc with limitations • Call CoreFoundation types directly • C++ is not allowed (should be wrapped in Objc) • Subclassing Swift classes not allowed in Objc

Slide 34

Slide 34 text

Objective-C bridging • NSArray < - > Array • NSDictionary < - > Dictionary • NSNumber - > Int, Double, Float

Slide 35

Slide 35 text

Objective-C bridging @objc class Foo { init (bar: String) { /*...*/ } }

Slide 36

Slide 36 text

Objective-C bridging @objc(objc_Foo) class Foo { ! @objc(initWithBar:) init (bar: String) { /*...*/ } ! }

Slide 37

Slide 37 text

Objective-C bridging Foo *foo = [[Foo alloc] initWithBar:@"Bar"];

Slide 38

Slide 38 text

Objective-C bridging func convertPoint(point: CGPoint, toWindow window: UIWindow!) -> CGPoint - (CGPoint)convertPoint:(CGPoint)point toWindow: (UIWindow *)window

Slide 39

Slide 39 text

Objective-C bridging • All object types are mapped as implicitly unwrapped optionals (T!) • All ‘id’ types are mapped as ‘AnyObject’

Slide 40

Slide 40 text

Swift internals • Swift objects are Obj-c objects • Implicit root class ‘SwiftObject’ • Ivars type encoding is stored separately • Method’s vtable • Name mangling

Slide 41

Slide 41 text

Name mangling class Foo { func bar() -> Bool { return false } } _TFC9test3Foo3barfS0_FT_Sb Swift keeps function metadata encoded in function symbols

Slide 42

Slide 42 text

Performance • 10-100 x slower than C++ (-O0) • 10 x slower than C++ (-O3) • 1 x as C++ (-Ofast)*

Slide 43

Slide 43 text

Performance • Swift is still in beta • Unoptimized calls of retain/release in loops

Slide 44

Slide 44 text

Cross-platform code #if os(iOS) typealias View = UView #else typealias View = NSView #endif ! class MyControl : View { }

Slide 45

Slide 45 text

Pattern matching let point = (0, 1) ! if point.0 >= 0 && point.0 <= 1 && point.1 >= 0 && point.1 <= 1 { println("I") } ! ...

Slide 46

Slide 46 text

Pattern matching let point = (0, 1) ! switch point { case (0...1, 0...1): println("I") … }

Slide 47

Slide 47 text

Pattern matching let point = (0, 1) ! switch point { case (0, 0): println("Point is at the origin") case (0...1, 0...1): println("I") case (-1...0, 0...1): println("II") case (-1...0, -1...0): println("III") case(0...1, -1...0): println("IV") default: println(“I don’t know.") }

Slide 48

Slide 48 text

Function currying func add(a: Int)(b: Int) -> Int { return a + b } ! let foo = add(5)(b: 3) // 8 ! let add5 = add(5) // (Int) -> Int let bar = add5(b: 3) // 8

Slide 49

Slide 49 text

Auto closures • Wraps function argument in explicit closure func assert(condition:() -> Bool, message: String) { #if DEBUG if !condition() { println(message) } #endif } ! assert({5 % 2 == 0}, "5 isn't an even number.")

Slide 50

Slide 50 text

Auto closures Wraps function argument in explicit closure func assert(condition: @auto_closure () -> Bool, message: String) { #if DEBUG if !condition() { println(message) } #endif } ! assert(5 % 2 == 0, "5 isn't an even number.")

Slide 51

Slide 51 text

Implicit type conversion struct Box { let _value : T init (_ value: T) { _value = value } } ! let boxedInt = Box(1) //Box

Slide 52

Slide 52 text

Implicit type conversion func foo(i: Int) {…} ! foo(boxedInt) //error: ’Box' is not convertible to 'Int'

Slide 53

Slide 53 text

Implicit type conversion extension Box { @conversion func __conversion() -> T { return _value } } ! ! foo(boxedInt) //success

Slide 54

Slide 54 text

Implicit type conversion • allows any type to be ‘nil’ (which has NilType) • allows toll-free-bridging with Cocoa types

Slide 55

Slide 55 text

Reflection struct Foo { var str = "Apple" let int = 13 func foo() { } } ! ! reflect(Foo()).count // 2 ! reflect(Foo())[0].0 // "str" reflect(Foo())[0].1.summary // "Apple

Slide 56

Slide 56 text

Direct call of C functions @asmname - allows to provide a Swift interface for C functions @asmname("my_c_func") func my_c_func(UInt64, CMutablePointer) -> CInt;

Slide 57

Slide 57 text

Scripting and REPL • xcrun swift - launches REPL • xcrun -i ‘file.swift’ - executes script

Slide 58

Slide 58 text

Where can I swift? • BDD Testing framework: Quick! • Reactive programming: RXSwift • Model mapping: Crust • Handy JSON processing: SwiftyJSON

Slide 59

Slide 59 text

Thx! @delebedev [email protected]

Slide 60

Slide 60 text

Credits • http://nondot.org/sabre/ • https://devforums.apple.com/thread/227288 • http://andelf.github.io/blog/2014/06/08/swift-implicit-type-cast/ • https://www.youtube.com/watch?v=Ii-02vhsdVk • http://www.eswick.com/2014/06/inside-swift/ • http://article.gmane.org/gmane.comp.compilers.clang.devel/37217 • http://stackoverflow.com/questions/24101718/swift-performance-sorting-arrays • http://www.splasmata.com/?p=2798 • https://github.com/rodionovd/SWRoute/wiki/Function-hooking-in-Swift