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

Swift, Meet Storyboard

Swift, Meet Storyboard

Swift London (October 19, 2015) talk. Talk about Natalie - Storyboard Code Generator presenting my approach to the "problem" of Storyboards and Swift.

Marcin Krzyzanowski

October 19, 2015
Tweet

More Decks by Marcin Krzyzanowski

Other Decks in Programming

Transcript

  1. Storyboards “A storyboard is a visual representation of the user

    interface of an iOS application, showing screens of content and the connections between those screens”
  2. Storyboard » graphical representation of a interface » visual editor:

    Interface Builder » not a code » structured XML document (compiled to nibs) » loaded in runtime
  3. Strings everywhere let storyboard = UIStoryboard(name: "Main", bundle: nil) let

    vc = storyboard.instantiateViewControllerWithIdentifier("MainViewController")
  4. Strings everywhere - refactoring week later storyboard.instantiateViewControllerWithIdentifier("ZweiMainViewController") *** Terminating app

    due to uncaught exception 'NSInvalidArgumentException', reason: 'Storyboard (<UIStoryboard: 0x7fea2871ccf0>) doesn't contain a view controller with identifier 'ZweiMainViewController'' *** First throw call stack: ( 0 CoreFoundation 0x0000000104f88f65 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000106c1adeb objc_exception_throw + 48 2 UIKit 0x0000000105e855d4 -[UIStoryboard instantiateInitialViewController] + 0 )
  5. Strings everywhere - Refactoring func performSegueWithIdentifier(identifier: String, sender: AnyObject?) ***

    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<NatalieExample.MainViewController: 0x7f93e2761eb0>) has no segue with identifier 'GoToMainView'' *** First throw call stack: ( 0 CoreFoundation 0x000000010634df65 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000107fdfdeb objc_exception_throw + 48 )
  6. Natalie » Open Source (github: krzyzanowskim/Natalie) » CLI tool »

    Swift script » #!/usr/bin/env xcrun -sdk macosx swift » Homebrew » $ brew install natalie
  7. View Controllers struct Storyboards { struct Main { static func

    instantiateViewController<T: UIViewController>(type: T.Type) -> T? static func instantiateMainViewController() -> MainViewController static func instantiateSecondViewController() -> ScreenTwoViewController } struct Settings { ... } } Instantiate view controllers: let vc = Storyboards.Main.instantiateViewConrtoller(MainViewConrtoller) let vc = Storyboards.Main.instantiateMainViewController() let vc = Storyboards.Main.instantiateSecondViewController() Notice: "vc" has right type:
  8. Segues extension MainViewController { enum Segue: String, CustomStringConvertible, SegueProtocol {

    case ScreenOneSegueButton = "Screen One Segue Button" var kind: SegueKind? // .Push, .Modal, etc... var identifier: String? var destination: UIViewController.Type? } }
  9. Segues var destination: UIViewController.Type? { switch (self) { case ScreenOneSegueButton:

    return ScreenOneViewController.self case ScreenOneSegue: return ScreenOneViewController.self } } in theory: MainViewController.Segue.ScreenOneSegue.destination!.init(nibName: nil, bundle: nil)
  10. Recap » Storyboard is external to the code » Strings

    are error prone » Swift is Strongly Typed » Middleman generator can create bridge between two worlds » Natalie