Clean Swift templates now updated for Xcode 8.3.3 & 9.0 and Swift 3 & 4

After many months of development and testing, experimenting with multiple projects, and initial beta testings by some of you, I have just released the Clean Swift templates to work for the latest Xcode 8.3.3 and 9.0. You can use it for Swift 3 and 4.

This update also has the following, long-awaited features:

  • Improved routing whether you use segues or not
  • Improved data passing using the all new data store protocol
  • Separated the routing process into two phases: navigation and data passing, with a clean interface
  • Removed the need for configurator in favor of cleaner setup
  • Combined input and output protocols to remove duplication
  • Renamed protocols with better names
  • Swiftier models with nested enums and structs
  • Use optionals to prevent crash in the VIP cycle when the scene is no longer in memory
  • Works whether you use storyboards to build your UI or not
  • View controller class names are now recognized when specifying class names in storyboards

I’ll be writing more about the new improvements in the coming weeks. In the meantime, you can check out the updated CleanStore sample app on GitHub to see how to use these latest templates.

A big thanks to those who tested early and provided me a long list of feedback and suggestions. I’ll read everything and see what I can push to the next update.

You can buy The Clean Swift Handbook now for a 50% early bird discount to get started with the latest templates, Xcode, and Swift.

Download the latest Clean Swift templates by subscribing below.

Get the Clean Swift Xcode Templates

Subscribe below to get my Xcode templates and learn how to apply the VIP cycle to your projects, extract business and presentation logic into interactor and presenter, navigate to different scenes using multiple storyboards, and write fast, maintainable tests with confidence to make changes.

I promise I'll never send you spam. You can unsubscribe at any time.

Raymond

I’ve been developing in iOS since the iPhone debuted, jumped on Swift when it was announced. Writing well-tested apps with a clean architecture has been my goal.

18 Comments

  1. In the Swift 3 version of your templates, there’s some errors when you create unit tests. You forgot to change NSBundle to Bundle and NSRunLoop, RunLoop and NSDate to Date in the ViewControllerTests.

    need to be changed to:

      1. Regarding your template update, when I test with Bundle.main, the test crash because of a cast error:

        Could not cast value of type ‘TestCleanSwift.ListOrdersViewController’ (0x107b4bf98) to ‘TestCleanSwiftTests.ListOrdersViewController’ (0x114cd25b8)

        It’s working fine with Bundle(for: type(of: self))

        1. This is working for me:

          func setupListOrdersViewController() {
          let bundle = Bundle.main
          let storyboard = UIStoryboard(name: “Main”, bundle: bundle)
          sut = storyboard.instantiateViewController(withIdentifier: “ListOrdersViewController”) as! ListOrdersViewController
          }

          func loadView() {
          window.addSubview(sut.view)
          RunLoop.current.run(until: Date())
          }

  2. Hey Raymond,
    What if I need to share some functionality amongst several scenes? How would you handle that case? E.g. I have a footer, which displays some value. That footer takes place on 4 screens. I wouldn’t want to copy paste the code to all the scenes where I need that functionality.

    1. Hi Andrey,

      What about creating a reusable UIView subclass to contain all your display logic in one place? And then supply it with the view models it needs to display your values? Finally, bubble up any user actions up to the view controllers and interactors to handle the business logic?

      This way, different scenes can respond differently to user button taps and whatnot. But your display logic is DRY.

      1. Who will responsible for supplying the view with view models in this case? If I’ll need to create several similar VIP cycles, then DRY principle won’t be met.

        1. Hi Andrey,

          Your view controllers will supply the views with the view models they receive from the presenters. The VIP cycle is unique to each scene. Don’t mix them. You can have many use cases passing through the VIP cycle. Don’t over-DRY things. If you have complex business logic in an interactor, you can extract it to a worker which can be shared between scenes.

          1. Still, this doesn’t look optimal. I have to define exact the same models in SceneModels and write exact the same method calls for all the scenes where I want to place the shared view. I’ll have to write exact same unit tests for that functionality for all the scenes. If I want to change the behaviour, I have to edit all models/interactors/presenters/unit tests and view controllers. There must be a better way, right?
            The only option coming to my mind is to have embedded controller.

  3. Why does the router inherit from NSObject?
    If you remove it, it is also working (doing everything in code, not storyboard)

    1. Hi Marco,

      The router inherits from NSObject so that the view controller’s prepare(for:sender:) method can invoke the routeToNextScene(segue:) methods by Objective-C selectors. This way, if you name your storyboard segue with the next scene’s name, it’s done automatically for you. You don’t have to manually dispatch the routing in the extra passDataToNextScene() method. I’ll be writing more about the routing process soon.

  4. Hi Raymond,

    I’m having trouble figuring out how to handle an alertController with multiple dynamic options.
    Currently, I’m creating the alertController in the presenter and passing only the object to the viewController, which is where I call viewModel.alert.addAction().
    How to handle the UIAlertAction handlers?? How should I create this dynamic alertActions, and where to handle the logic for it? In the viewController or in the presenter?

    1. Hi Mauricio,

      When you have multiple dynamic options for the alert, that means the title, message, and buttons will change depending on different success/failure/error conditions, right?

      If that’s the case, creating the UIAlertController in the presenter makes the most sense.

      When the user interacts with the alert, it should be the view controller’s job to handle it and invoke the interactor for any possible use case that should be triggered as a result of the user tapping a button on the alert. From then on, you can go through the VIP cycle again.

Leave a Comment

Your email address will not be published. Required fields are marked *