Pro Yearly is on sale from $80 to $50! »

Going Swift and Beyond // First Wave Swift

D3c5f7382824133c2718c8effb5894fb?s=47 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.

D3c5f7382824133c2718c8effb5894fb?s=128

Ayaka Nonaka

January 29, 2016
Tweet

Transcript

  1. GOING SWIFT AND BEYOND @AYANONAGON DOTSWIFT 2016

  2. 2013

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

  5. BORROWED IDEAS

  6. None
  7. FIRST WAVE SWIFT

  8. WHAT HOW WHY

  9. WHAT

  10. None
  11. None
  12. struct Story { let ID: String let title: String let

    message: String let sender: User let recipient: User let date: NSDate // ... }
  13. class StoriesViewController: UIViewController { let stories: [Story] // ... }

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

  15. 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) } // ... }
  16. url_scheme://stories/12345

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

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

  19. 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. } }
  20. 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? }
  21. 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 } } } }
  22. url_scheme://stories/12345 StoryContainerViewController(storyID: "12345")

  23. url_scheme://stories/12345

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

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

  26. protocol RemoteContentCoordinator { typealias Content func fetchContent(completion: Result<Content, Error> ->

    Void) func viewControllerForContent(content: Result<Content, Error>) -> UIViewController }
  27. class RemoteContentContainerViewController<T: RemoteContentCoordinator>: 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) } } }
  28. struct StoryCoordinator: RemoteContentCoordinator { let ID: String func fetchContent(completion: Result<Story,

    Error> -> Void) { client.showStory(ID: ID, completion: completion) } func viewControllerForContent(content: Result<Story, Error>) -> UIViewController { switch content { case .Success(let story): return StoryDetailViewController(story: story) case .Error(_): return ErrorViewController(title: "Could not find story.") } } }
  29. url_scheme://stories/12345 let coordinator = StoryCoordinator(ID: "12345") RemoteContentContainerViewController(coordinator: coordinator)

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

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

  32. 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? }
  33. 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) } // ... }
  34. HOW

  35. SWIFT IS OPEN-SOURCE

  36. GITHUB.COM/APPLE/ SWIFT

  37. GITHUB.COM/APPLE/ SWIFT-EVOLUTION

  38. None
  39. None
  40. 80% PLANNING 20% CODING

  41. WHY

  42. GENERICS ENUMS PROTOCOLS

  43. GENERICS ENUMS PROTOCOLS

  44. OPTIONALS VALUE-TYPES FUNCTIONAL

  45. OPTIONALS VALUE-TYPES FUNCTIONAL

  46. SO, WHY?

  47. SHIP A GREAT PRODUCT THAT USERS LOVE

  48. SHARE

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

  50. TRY

  51. TRY > Fix a bug in backend or web code

    > Learn a different language > Talk about architecture with an Android(!) engineer
  52. INCLUDE

  53. INCLUDE > Get them excited about Swift > Be open

    to unfamiliar ideas > Be welcoming
  54. THANK YOU MERCI BEAUCOUP

  55. None