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

Going Swift and Beyond // First Wave Swift

Ayaka Nonaka
January 29, 2016

Going Swift and Beyond // First Wave Swift

Talk given 29 Jan 2016 at dotSwift Paris

Swift is a language that brings a lot of great new features like optionals, generics, and first-class enums. How do these new features affect the way we architect our apps? Do the same design patterns from Objective-C still apply in Swift? We’ll go over a specific example of how Swift affects what kind of code we write, how we write our code, and even a bit of why we do what we do.

Ayaka Nonaka

January 29, 2016
Tweet

More Decks by Ayaka Nonaka

Other Decks in Technology

Transcript

  1. GOING SWIFT
    AND BEYOND
    @AYANONAGON
    DOTSWIFT 2016

    View full-size slide

  2. 1. NeXTSTEP
    2. OS X
    3. iOS

    View full-size slide

  3. BORROWED
    IDEAS

    View full-size slide

  4. FIRST WAVE
    SWIFT

    View full-size slide

  5. struct Story {
    let ID: String
    let title: String
    let message: String
    let sender: User
    let recipient: User
    let date: NSDate
    // ...
    }

    View full-size slide

  6. class StoriesViewController: UIViewController {
    let stories: [Story]
    // ...
    }

    View full-size slide

  7. class StoryDetailViewController: UIViewController {
    init(story: Story)
    }

    View full-size slide

  8. class StoryDetailViewController: UIViewController {
    private let titleView: StoryTitleView
    private let senderView: AvatarView
    private let recipientView: AvatarView
    private let dateLabel: DateLabel
    init(story: Story) {
    titleView = StoryTitleView(story: story)
    senderView = AvatarView(user: story.sender)
    recipientView = AvatarView(user: story.recipient)
    dateLabel = DateLabel(date: story.date)
    }
    // ...
    }

    View full-size slide

  9. url_scheme://stories/12345

    View full-size slide

  10. class StoryDetailViewController: UIViewController {
    init(story: Story)
    }

    View full-size slide

  11. class StoryDetailViewController: UIViewController {
    init(story: Story)
    init(storyID: String)
    }

    View full-size slide

  12. class StoryDetailViewController: UIViewController {
    private let titleView: StoryTitleView
    private let senderView: AvatarView
    private let recipientView: AvatarView
    private let dateLabel: DateLabel
    init(story: Story) { /* Same as before */ }
    init(storyID: String) {
    // Hmmmmmmm.
    }
    }

    View full-size slide

  13. class StoryDetailViewController: UIViewController {
    let storyID: String
    private var titleView: StoryTitleView?
    private var senderView: AvatarView?
    private var recipientView: AvatarView?
    private var dateLabel: DateLabel?
    init(story: Story) { /* Same as before */ }
    init(storyID: String) {
    self.storyID = storyID
    titleView = nil
    senderView = nil
    recipientView = nil
    dataLabel = nil
    }
    // Load everything from API in viewDidLoad?
    }

    View full-size slide

  14. class StoryContainerViewController: UIViewController {
    let storyID: String
    init(storyID: String) {
    self.storyID = storyID
    }
    override func viewDidLoad() {
    client.showStory(ID: storyID) { result in
    switch result {
    case .Success(let story):
    let viewController = StoryDetailViewController(story: story)
    self.addChildViewController(viewController)
    self.view.addSubview(viewController.view)
    viewController.view.frame = view.bounds
    viewController.didMoveToParentViewController(self)
    case .Error(let error): // Show error
    }
    }
    }
    }

    View full-size slide

  15. url_scheme://stories/12345
    StoryContainerViewController(storyID: "12345")

    View full-size slide

  16. url_scheme://stories/12345

    View full-size slide

  17. url_scheme://stories/12345
    url_scheme://users/007

    View full-size slide

  18. url_scheme://stories/12345
    url_scheme://users/007
    url_scheme://messages/9876

    View full-size slide

  19. protocol RemoteContentCoordinator {
    typealias Content
    func fetchContent(completion: Result -> Void)
    func viewControllerForContent(content: Result) -> UIViewController
    }

    View full-size slide

  20. class RemoteContentContainerViewController: UIViewController {
    let coordinator: T
    init(coordinator: T) {
    self.remoteContentCoordinator = remoteContentCoordinator
    super.init(nibName: nil, bundle: nil)
    }
    override func viewDidLoad() {
    super.viewDidLoad()
    coordinator.fetchContent { content in
    let viewController = self.coordinator.viewControllerForContent(content)
    self.addChildViewController(viewController)
    self.view.addSubview(viewController.view)
    viewController.view.frame = view.bounds
    viewController.didMoveToParentViewController(self)
    }
    }
    }

    View full-size slide

  21. struct StoryCoordinator: RemoteContentCoordinator {
    let ID: String
    func fetchContent(completion: Result -> Void) {
    client.showStory(ID: ID, completion: completion)
    }
    func viewControllerForContent(content: Result) -> UIViewController {
    switch content {
    case .Success(let story): return StoryDetailViewController(story: story)
    case .Error(_): return ErrorViewController(title: "Could not find story.")
    }
    }
    }

    View full-size slide

  22. url_scheme://stories/12345
    let coordinator = StoryCoordinator(ID: "12345")
    RemoteContentContainerViewController(coordinator: coordinator)

    View full-size slide

  23. url_scheme://users/007
    let coordinator = UserCoordinator(ID: "007")
    RemoteContentContainerViewController(coordinator: coordinator)

    View full-size slide

  24. url_scheme://messages/9876
    let coordinator = MessageCoordinator(ID: "9876")
    RemoteContentContainerViewController(coordinator: coordinator)

    View full-size slide

  25. class StoryDetailViewController: UIViewController {
    let storyID: String
    private var titleView: StoryTitleView?
    private var senderView: AvatarView?
    private var recipientView: AvatarView?
    private var dateLabel: DateLabel?
    init(story: Story) { /* Same as before */ }
    init(storyID: String) {
    self.storyID = storyID
    titleView = nil
    senderView = nil
    recipientView = nil
    dataLabel = nil
    }
    // Load everything from API in viewDidLoad?
    }

    View full-size slide

  26. class StoryDetailViewController: UIViewController {
    private let titleView: StoryTitleView
    private let senderView: AvatarView
    private let recipientView: AvatarView
    private let dateLabel: DateLabel
    init(story: Story) {
    titleView = StoryTitleView(story: story)
    senderView = AvatarView(user: story.sender)
    recipientView = AvatarView(user: story.recipient)
    dateLabel = DateLabel(date: story.date)
    }
    // ...
    }

    View full-size slide

  27. SWIFT IS OPEN-SOURCE

    View full-size slide

  28. GITHUB.COM/APPLE/
    SWIFT

    View full-size slide

  29. GITHUB.COM/APPLE/
    SWIFT-EVOLUTION

    View full-size slide

  30. 80% PLANNING
    20% CODING

    View full-size slide

  31. GENERICS
    ENUMS
    PROTOCOLS

    View full-size slide

  32. GENERICS
    ENUMS
    PROTOCOLS

    View full-size slide

  33. OPTIONALS
    VALUE-TYPES
    FUNCTIONAL

    View full-size slide

  34. OPTIONALS
    VALUE-TYPES
    FUNCTIONAL

    View full-size slide

  35. SHIP A GREAT
    PRODUCT THAT
    USERS LOVE

    View full-size slide

  36. SHARE
    > Write
    > Speak
    > Recommend books / articles

    View full-size slide

  37. TRY
    > Fix a bug in backend or web code
    > Learn a different language
    > Talk about architecture with an Android(!) engineer

    View full-size slide

  38. INCLUDE
    > Get them excited about Swift
    > Be open to unfamiliar ideas
    > Be welcoming

    View full-size slide

  39. THANK YOU
    MERCI BEAUCOUP

    View full-size slide