Clean Code in Swift: Principles and Examples for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Clean Code in Swift: Principles and Examples for Beginners



Every iOS or macOS developer sooner or later faces a problem: code that worked perfectly yesterday becomes unreadable today. This is not a flaw of the Swift language — it is the result of neglecting the principles of Clean Code. Clean code is not just about aesthetics. It is the foundation of project maintainability, reduced debugging time, and comfortable teamwork. In this article, we will break down the key principles of Clean Code with Swift examples that will help you write code understandable not only to the computer but also to people.



1. Naming: Variables, Constants, and Functions



The first and most important principle — the name should answer the question "Why?", not "How?". In Swift, thanks to strong typing, you can omit the type in the name, but not the intent.



Bad example:

var d: Double = 3.14var arr = [String]()func calc(a: Double, b: Double) -> Double {    return a * b}


Good example (Clean Code):

let piValue: Double = 3.14159var userNames: [String] = []func calculateRectangleArea(width: Double, height: Double) -> Double {    return width * height}


Naming rules in Swift:

  • Use camelCase for variables and functions.
  • Avoid abbreviations ( btn → submitButton ).
  • For boolean variables, use prefixes is, has, should (e.g., isUserLoggedIn).
  • Function names should start with a verb: fetchData(), saveToCache().


2. Functions: One Task — One Function



The Single Responsibility principle applies not only to classes but also to functions. If a function does more than one thing — it needs to be split.



Bad example: function does everything at once

func processUserData(user: User) {    // Validation    guard user.email.contains("@") else { return }    // Save to database    Database.shared.save(user)    // Send notification    NotificationCenter.default.post(name: .userDidRegister, object: nil)    // Update UI    DispatchQueue.main.async {        self.label.text = "Welcome, \\(user.name)"    }}


Good example: split into small functions

func registerUser(_ user: User) {    guard validateUser(user) else { return }    saveUserToDatabase(user)    postRegistrationNotification()    updateUI(for: user)}

private func validateUser(_ user: User) -> Bool { return user.email.contains("@") && !user.name.isEmpty}

private func saveUserToDatabase(_ user: User) { Database.shared.save(user)}

private func postRegistrationNotification() { NotificationCenter.default.post(name: .userDidRegister, object: nil)}

private func updateUI(for user: User) { DispatchQueue.main.async { self.welcomeLabel.text = "Welcome, \\(user.name)" }}


Tip: If you can't come up with a short name for a function, it's likely doing too much.



3. Comments: Less is Better, but Accurate



In Clean Code, comments are a sign of bad code. Good code should document itself. However, there are exceptions: complex business logic, working with legacy code, or public APIs.



Redundant comment (bad):

// Increment counter by 1counter += 1


Useful comment (good):

// Use Decimal to avoid rounding errors when working with currencylet price = Decimal(string: "19.99") ?? .zero


Rules for working with comments:

  • Don't write the obvious — the code reads itself.
  • Use // MARK: - for

Blogs

Book Recommendations