Lessons from Production Swift

Lessons from Production Swift

This is a presentation I gave at Istanbul Tech Talks about my work writing Swift in production. It discusses why we need Swift, some problems I've faced using it, and how it enables new problem-solving techniques.

http://www.istanbultechtalks.com

0ebf471a3ae8df42a84f93a7efbbdbd0?s=128

Ash Furrow

April 27, 2015
Tweet

Transcript

  1. 4.

    1. The Need for Swift 2. The Fast and the

    Faulty 3. Seek Out Bold New Worlds
  2. 7.

    TXS ;push return address back onto stack LDY #$00 ;load

    Y with zero - will hold result LOOP1 LDAA TEMP ;load A into TEMP ANDA MASK ;AND A with Mask BNE ADD1 BRA NONE1 ADD1 INY ;increment our counter of 1's NONE1 LDAA TEMP ;reload accumulator A LSL MASK ;Shift the mask's 1 bit left BNE LOOP1 ;If we haven't finished our loop, branch LDAA #$01 ;load new mask into A STAA MASK ;store the reset mask into MASK TSX ;pull of return address and store in X PULA ;pull off A STAA TEMP ;store the value into temp TXS ;push return address back onto the stack LOOP2 LDAA TEMP ;Load A into TEMP ANDA MASK ;logical AND MASK with A BNE ADD2 ;add one if we need to BRA NONE2 ADD2 INY ;increment our counter of 1's NONE2 LDAA TEMP LSL MASK ;shift our mask left by one BNE LOOP2 ;loop back until we've exhausted positions STY TEMP ;store Y into TEMP - this is the number of 1's LDAB TEMP ;load the number of 1's into B LDAA #$10 ;load dec 16 into A SBA ;A - B -> A same as 16 - B -> A
  3. 11.

    Criteria 1. No C baggage 2. Memory Managed 3. Native

    unicode strings 4. Native collections 5. Be concise 6. Named Parameters
  4. 12.

    Criteria 1. No C baggage 2. Memory Managed 3. Native

    unicode strings 4. Native collections 5. Be concise 6. Named Parameters
  5. 13.

    The Need for Swift • Programming abstraction increases over time

    • Objective-C has improved all it can • Swift is the next step • Revolution, not evolution
  6. 15.

    Problems In Beta • Xcode crashes • Compiler segfaults •

    Constant changes to Swift • Many language limitations
  7. 16.

    Problems Now • Still some stability issues • Still frequent

    changes to Swift • Still some remaining language limitations
  8. 17.

    Problems Now • Language changes tied to Xcode versions •

    Runtime changes tied to Xcode versions • Changes in resource-loading in frameworks
  9. 18.

    Community Tools • Most still in their infancy • CocoaPods,

    Jazzy, SBConstants… • The rest do not exist (or are still in beta) • Test coverage analyzer
  10. 20.

    The Fast and the Faulty • Swift had a rough

    start • Was to be expected • Things are better now • Mostly • Growing pains
  11. 23.
  12. 24.

    Index Paths • Used to identify cells in a table

    view • Section, row • Lots of horrendous code • It’s so bad • Seriously bad
  13. 25.

    Index Paths if (indexPath.section == 0) { if (indexPath.row ==

    0) { } else if (indexPath.row == 1) { 
 } else if ... } else if (indexPath.section == 1) { if (indexPath.row == 0) { } else if (indexPath.row == 1) { 
 } else if ... } else if ...
  14. 26.

    Index Paths switch (indexPath.section, indexPath.row) { case (0, 0): case

    (0, 1): case (1, 0): case (1, 1): default: // nop }
  15. 28.

    Index Paths switch (indexPath.section, indexPath.row) { case (0, let row):

    // Executed for any section 0, row is row case (let section, 0) where section % 2 == 1: // Executed for first rows of odd all sections case (let section, let row) where validate(section): // Executed when validate() returns true default: // Executed on all other cases }
  16. 29.

    Generics • Define functions, structs, others in the abstract •

    Create one instead of many • Arrays, dictionaries, and sets are all generics
  17. 30.

    Generics struct Stack<T> { private var contents = Array<T>() mutating

    func push(value: T) { contents.insert(value, atIndex: 0) } mutating func pop() -> T { return contents.removeAtIndex(0) } var isEmpty: Bool { return countElements(contents) == 0 } }
  18. 31.

    Generics var intStack = Stack<Int>() var stringStack = Stack<String>() var

    stackStack = Stack<Stack<AnyObject>>() intStack.push(1) intStack.pop() // Returns 1
  19. 32.

    Lazy Loading • Create resource when it is first accessed

    • Avoids unnecessary work for CPU • Avoids unnecessary memory use
  20. 33.
  21. 34.

    Lazy Objective-C @interface MyClass: NSObject @property (nonatomic, copy) NSString *name;

    @end @implementation - (NSString *)name { if (_name == nil) { _name = "Ash Furrow"; } return _name; } @end
  22. 36.

    Lazy Swift class MyClass { lazy var name = "Ash

    Furrow" } MyClass().name // Returns "Ash Furrow" let instance = MyClass() instance.name = "Orta Therox" instance.name // Returns “Orta Therox"
  23. 37.

    Lazy Swift class MyClass { lazy var name = "Ash

    Furrow” lazy var greeting: String = { return "Hello, \(self.name)" }() } MyClass().greeting // Returns "Hello, Ash Furrow" let instance = MyClass() instance.name = "Orta Therox" instance.greeting // Returns "Hello, Orta Therox" instance.name = "Eloy Durán" instance.greeting // Returns "Hello, Orta Therox"
  24. 38.

    Extending Types • Objective-C has “categories” for extending existing classes

    • Swift has “extensions” instead • They work on all types
  25. 39.

    Extending Types extension Int { func times(closure: () -> ())

    { for i in 0..<self { closure() } } } 4.times { // Do something 4 times }
  26. 40.

    Extending Types extension Int { var hours: NSTimeInterval { return

    NSTimeInterval(3600 * self) } } extension NSTimeInterval { var fromNow: NSDate { return NSDate(timeIntervalSinceNow: self) } var ago: NSDate { NSDate(timeIntervalSinceNow: -self) } } 4.hours.fromNow 4.hours.ago
  27. 41.

    Functional Awesomeness let people = ["Carter", "Sebastian", "Daniel"] people.map {

    "Hello, \($0)!" } func hello(name: String) -> String { return "Hello, \(name)!" } people.map(hello) or…
  28. 42.

    Functional Awesomeness func say(greeting: String) -> (name: String) -> String

    { return { (name: String) -> String in "(greeting), \(name)!" } } people.map(say("Hello")) people.map(say("Merhaba"))
  29. 43.

    Functional Awesomeness func say(greeting: String)(name: String) -> String { return

    "(greeting), \(name)!" } people.map(say("Hello")) people.map(say("Merhaba"))
  30. 45.

    SBConstants func performSegue(identifier: SegueIdentifier) { performSegueWithIdentifier(identifier.rawValue, sender: self) } ...

    func ==(lhs: UIStoryboardSegue, rhs: SegueIdentifier) -> Bool { return lhs.identifier == rhs.rawValue }
  31. 47.

    SBConstants • Don’t use rawValue all over the place •

    Abstract it away • Get compile-time safety
  32. 50.

    Resources • Natasha the Robot’s newsletter • iOSDevWeekly • iOS

    Goodies • GitHub Explore • leanpub.com/yourfirstswiftapp
  33. 51.
  34. 52.

    1. The Need for Swift 2. The Fast and the

    Faulty 3. Seek Out Bold New Worlds