This simple app example shows how clean architecture separates data, logic, and UI. The ViewController prints task titles using the ViewModel and Use Case layers.
import UIKit
// Entity
struct Task {
let id: Int
let title: String
}
// Use Case
protocol TaskUseCase {
func getTasks() -> [Task]
}
class TaskInteractor: TaskUseCase {
func getTasks() -> [Task] {
return [Task(id: 1, title: "Buy milk"), Task(id: 2, title: "Walk dog")]
}
}
// ViewModel
class TaskViewModel {
private let useCase: TaskUseCase
var tasksTitles: [String] = []
init(useCase: TaskUseCase) {
self.useCase = useCase
}
func loadTasks() {
tasksTitles = useCase.getTasks().map { $0.title }
}
}
// ViewController
class TaskViewController: UIViewController {
var viewModel: TaskViewModel!
override func viewDidLoad() {
super.viewDidLoad()
viewModel.loadTasks()
for title in viewModel.tasksTitles {
print(title)
}
}
}
// Simulate app start
let interactor = TaskInteractor()
let viewModel = TaskViewModel(useCase: interactor)
let viewController = TaskViewController()
viewController.viewModel = viewModel
viewController.viewDidLoad()