Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Ash Furrow

April 27, 2015
Tweet

More Decks by Ash Furrow

Other Decks in Programming

Transcript

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

    Faulty 3. Seek Out Bold New Worlds
  2. 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. Criteria 1. No C baggage 2. Memory Managed 3. Native

    unicode strings 4. Native collections 5. Be concise 6. Named Parameters
  4. Criteria 1. No C baggage 2. Memory Managed 3. Native

    unicode strings 4. Native collections 5. Be concise 6. Named Parameters
  5. 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. Problems In Beta • Xcode crashes • Compiler segfaults •

    Constant changes to Swift • Many language limitations
  7. Problems Now • Still some stability issues • Still frequent

    changes to Swift • Still some remaining language limitations
  8. Problems Now • Language changes tied to Xcode versions •

    Runtime changes tied to Xcode versions • Changes in resource-loading in frameworks
  9. Community Tools • Most still in their infancy • CocoaPods,

    Jazzy, SBConstants… • The rest do not exist (or are still in beta) • Test coverage analyzer
  10. The Fast and the Faulty • Swift had a rough

    start • Was to be expected • Things are better now • Mostly • Growing pains
  11. Index Paths • Used to identify cells in a table

    view • Section, row • Lots of horrendous code • It’s so bad • Seriously bad
  12. 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 ...
  13. Index Paths switch (indexPath.section, indexPath.row) { case (0, 0): case

    (0, 1): case (1, 0): case (1, 1): default: // nop }
  14. 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 }
  15. Generics • Define functions, structs, others in the abstract •

    Create one instead of many • Arrays, dictionaries, and sets are all generics
  16. 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 } }
  17. Generics var intStack = Stack<Int>() var stringStack = Stack<String>() var

    stackStack = Stack<Stack<AnyObject>>() intStack.push(1) intStack.pop() // Returns 1
  18. Lazy Loading • Create resource when it is first accessed

    • Avoids unnecessary work for CPU • Avoids unnecessary memory use
  19. Lazy Objective-C @interface MyClass: NSObject @property (nonatomic, copy) NSString *name;

    @end @implementation - (NSString *)name { if (_name == nil) { _name = "Ash Furrow"; } return _name; } @end
  20. 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"
  21. 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"
  22. Extending Types • Objective-C has “categories” for extending existing classes

    • Swift has “extensions” instead • They work on all types
  23. Extending Types extension Int { func times(closure: () -> ())

    { for i in 0..<self { closure() } } } 4.times { // Do something 4 times }
  24. 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
  25. Functional Awesomeness let people = ["Carter", "Sebastian", "Daniel"] people.map {

    "Hello, \($0)!" } func hello(name: String) -> String { return "Hello, \(name)!" } people.map(hello) or…
  26. Functional Awesomeness func say(greeting: String) -> (name: String) -> String

    { return { (name: String) -> String in "(greeting), \(name)!" } } people.map(say("Hello")) people.map(say("Merhaba"))
  27. Functional Awesomeness func say(greeting: String)(name: String) -> String { return

    "(greeting), \(name)!" } people.map(say("Hello")) people.map(say("Merhaba"))
  28. SBConstants func performSegue(identifier: SegueIdentifier) { performSegueWithIdentifier(identifier.rawValue, sender: self) } ...

    func ==(lhs: UIStoryboardSegue, rhs: SegueIdentifier) -> Bool { return lhs.identifier == rhs.rawValue }
  29. SBConstants • Don’t use rawValue all over the place •

    Abstract it away • Get compile-time safety
  30. Resources • Natasha the Robot’s newsletter • iOSDevWeekly • iOS

    Goodies • GitHub Explore • leanpub.com/yourfirstswiftapp
  31. 1. The Need for Swift 2. The Fast and the

    Faulty 3. Seek Out Bold New Worlds