Clean Swift(VIP Architecture) Tutorial in UIKit for beginners — Part 3

Hoyeon Lee
3 min readDec 15, 2023

--

Step 4: Settings for View and ViewController

View

  • View inherits UIView and has UITextField and UIButton. In this example, since the UI is not actually implemented, we will skip setting up auto-layout.
  • When the user taps the button on the View, buttonTapped method will be executed in the ViewController.
  • Here, ViewDelegate protocol enables 1:1 communication between View and ViewController.

ViewController

  • ViewController inherits UIViewController and conforms to ViewDelegate and DisplayProcessable protocols.
  • ViewController references View, Interactor(BusinessProcessable? type), Router(RoutingProcessable? type), and Configurator.
  • Set this ViewController as a delegate of View and call configure method in Configurator when ViewController is initialized.
  • When the buttonTapped method is called, ViewController will ask Interactor to perform calculation with Model.Calculation.Request which has three numbers(10, 20, and 30).
  • NextViewController is just created to suppose that scene transitions occur in the app. It’s not an important code in the example.

Step 5: Settings for Interactor and Worker

Interactor

  • Interactor conforms to BusinessProcessable protocol.
  • Interactor references Presenter(PresentationProcessable? type) and Worker(WorkingProcessable? type).
  • When startCalculation method is called, Interactor will ask Worker to run addGivenNumbers asynchronously with Model.Calculation.Request. (These should be placed inside a Task block)
  • After then, Interactor will receive Model.Calculation.Response from the Worker and ask Presenter to convert Model.Calculation.Response to Model.Calculation.ViewModel.

Worker

  • Worker conforms to WorkingProcessable protocol.
  • Worker takes heavy tasks such as CRUD to Database or networking while Interactor is processing its business logic. So, it is supporting interactor and thus creating Worker would be optional depending on your situation.
  • For the asynchronous execution, the addGivenNumbers requires async keyword.
  • The reason for using the sleep function is to assume that a task will take a long time.

Step 6: Settings for Presenter

Presenter

  • Presenter conforms to PresentationProcessable protocol.
  • Presenter has weak reference to ViewController(DisplayProcessable? type).
  • When convertResponseToViewModel method is called by Interactor, the data format will be changed to one more suitable for display.
  • For example, if the response of calculation is 10, then result message would be “The answer is 60.” which will be formatted as Model.Calculation.ViewModel.
  • Finally, Presenter will ask ViewController to run printResultMessageOnTheConsole which is responsible for printing out the result message on the console.

Step 7: Settings for Router and Configurator

Router

  • Router conforms to RoutingProcessable protocol.
  • Router plays a role in controlling navigation.
  • Router has weak reference to ViewController.
  • When your app has multiple scenes and user want navigation to the next scene, make your ViewController call navigateToNextScene method in Router.

Configurator

  • Configurator is a singleton class.
  • Configurator creates instance of Router, Presenter, and Interactor and inject dependencies.

Step 8: Run The Code

Now all components consisting of the architecture have been set up. But, we still have one more thing!

Do you remember that we’re assuming the user enters three numbers into a text field and clicks the Calculate button in this tutorial?

If you run Playground with only the code that we’ve written so far, no message will appear in the console. We should inject dependencies into ViewController to make the VIP cycle work.

It’s like completing the last piece of a puzzle, so add the code below.

Finally we have the complete code. The full code is as follows.

When you run the code, you should see the same message like below.

Calculation started → sleep(3) → Calculation finished → Print answer message

Summary

Yeah! We’ve finally completed the Clean Swift (VIP architecture) tutorial! If you find this tutorial difficult, refer to following flowchart and slowly understand it again.

Flowchart of the tutorial (Blue is UI layer and green is business logic layer)

In this tutorial, we’ve learned about Clean Swift, or VIP (View + Interactor + Presenter) architecture.

Compared to traditional patterns such as MVC and MVVM, this architecture separates the responsibilities of each component more clearly, improving the maintainability, testability, and scalability of the application.

I hope this tutorial gave you a basic understanding of Clean Swift architecture. You may find it difficult when you first study it, but once you understand it, you will realize that it is an architecture suitable for long-term and large-scale projects.

And based on what you learned in this tutorial, try applying it to a project with more scenes, more use cases, and heavier logic :)

--

--