Swift Style Guide

Best practices and conventions for writing clean Swift code

📝 What is a Swift Style Guide?

A Swift style guide provides consistent coding conventions and best practices. Following these guidelines makes your code more readable, maintainable, and professional for team collaboration and personal projects.


// Good style example
class UserManager {
    private let networkService: NetworkService
    
    func fetchUser(by id: String) -> User? {
        return networkService.getUser(id: id)
    }
}
                                    

Output:

Clean, readable Swift code following style conventions

Key Style Principles

📖

Readability

Code should be easy to read

let userName = "John"
🎯

Consistency

Follow the same patterns

func calculateTotal() { }
🔧

Maintainability

Easy to modify and extend

protocol DataSource { }
👥

Collaboration

Team-friendly conventions

// MARK: - Public Methods

🔹 Naming Conventions

Use clear, descriptive names that follow Swift conventions:

// ✅ Good naming
class UserProfileViewController {
    private let userService: UserService
    private var isLoading = false
    
    func fetchUserProfile(for userId: String) {
        // Implementation
    }
    
    private func updateUI() {
        // Implementation
    }
}

// ❌ Poor naming
class UPV {
    var us: UserService
    var il = false
    
    func fup(u: String) {
        // Hard to understand
    }
}

Best Practices:

  • Use camelCase for variables and functions
  • Use PascalCase for classes and protocols
  • Be descriptive but concise
  • Avoid abbreviations

🔹 Code Organization

Structure your code with clear sections and proper spacing:

import UIKit
import Foundation

// MARK: - Protocol Definition
protocol UserManagerDelegate: AnyObject {
    func userDidLogin(_ user: User)
    func userDidLogout()
}

// MARK: - Main Class
class UserManager {
    
    // MARK: - Properties
    weak var delegate: UserManagerDelegate?
    private let apiService: APIService
    private var currentUser: User?
    
    // MARK: - Initialization
    init(apiService: APIService) {
        self.apiService = apiService
    }
    
    // MARK: - Public Methods
    func login(email: String, password: String) {
        // Login implementation
    }
    
    func logout() {
        currentUser = nil
        delegate?.userDidLogout()
    }
    
    // MARK: - Private Methods
    private func validateCredentials(_ email: String, _ password: String) -> Bool {
        return !email.isEmpty && !password.isEmpty
    }
}

Organization Tips:

  • Use MARK comments to organize sections
  • Group related functionality together
  • Order: Properties → Init → Public → Private
  • Add blank lines between sections

🔹 Formatting Guidelines

Consistent formatting makes code easier to read:

// ✅ Good formatting
func processUserData(
    users: [User],
    completion: @escaping (Result<[ProcessedUser], Error>) -> Void
) {
    guard !users.isEmpty else {
        completion(.failure(ProcessingError.emptyData))
        return
    }
    
    let processedUsers = users.compactMap { user in
        return ProcessedUser(
            id: user.id,
            name: user.fullName,
            email: user.email.lowercased()
        )
    }
    
    completion(.success(processedUsers))
}

// ✅ Good array/dictionary formatting
let userPreferences = [
    "theme": "dark",
    "notifications": true,
    "language": "en"
]

let colors = [
    .red,
    .green,
    .blue
]

Formatting Rules:

  • Use 4 spaces for indentation
  • Break long lines at 100-120 characters
  • Align parameters vertically when breaking
  • Use trailing commas in multi-line collections

🔹 Comments and Documentation

Write meaningful comments and documentation:

/**
 A service responsible for managing user authentication and profile data.
 
 This class handles login, logout, and profile updates while maintaining
 secure storage of user credentials and session information.
 */
class AuthenticationService {
    
    /**
     Authenticates a user with email and password.
     
     - Parameters:
        - email: The user's email address
        - password: The user's password
        - completion: Called when authentication completes
     
     - Returns: A cancellable authentication task
     */
    func authenticate(
        email: String,
        password: String,
        completion: @escaping (Result) -> Void
    ) -> AuthTask {
        // TODO: Implement OAuth2 flow
        // FIXME: Handle network timeout properly
        
        // Validate input parameters
        guard isValidEmail(email) else {
            completion(.failure(.invalidEmail))
            return AuthTask()
        }
        
        // Perform authentication
        return performAuthentication(email: email, password: password, completion: completion)
    }
}

Comment Guidelines:

  • Use /// for documentation comments
  • Explain WHY, not WHAT
  • Use TODO and FIXME appropriately
  • Document public APIs thoroughly

🧠 Test Your Knowledge

What naming convention should you use for Swift class names?