iOS Coding Standard (Swift)

1. Objective

To ensure all iOS applications developed at [Your Company Name] follow a consistent, high-quality, and maintainable coding approach that aligns with organizational and industry best practices.

2. Scope

This document applies to all iOS, iPadOS, and macOS development projects using Swift (and Objective-C for interoperability), developed in Xcode, and maintained under [Your Company Name]'s repositories.

3. Architecture & Project Structure

Adopt MVVM (Model-View-ViewModel), as it integrates seamlessly with both SwiftUI and UIKit (with Combine or async/await). Maintain a consistent project folder structure, grouped by feature:

AppName/
├── Application/ // AppDelegate, SceneDelegate, Info.plist
├── Features/ // One folder per app feature (e.g.,
Profile, Home)
│ ├── Home/
│ │ ├── Model/ // HomeModels.swift
│ │ ├── View/ // HomeView.swift (SwiftUI) or
HomeViewController.swift (UIKit)
│ │ └── ViewModel/ // HomeViewModel.swift
│ ├── Profile/
│ │ ├── Model/
│ │ ├── View/
│ │ └── ViewModel/
├── Data/
│ ├── Network/ // APIService.swift, NetworkError.swift
│ ├── Persistence/ // CoreData, SwiftData,
KeychainService.swift
│ └── Models/ // Shared data models (e.g., User.swift)
├── Utilities/ // Helpers, Extensions, Constants.swift
├── Resources/ // Assets.xcassets, Localizable.strings
└── DI/ // Dependency Injection container (if used)
  • Key Principle: Separate business logic from UI logic.
  • Avoid "Massive View Controllers." ViewControllers (UIKit) or Views (SwiftUI) should be "dumb" and only responsible for displaying data and forwarding user events to the ViewModel.

4. Naming Conventions

Follow Apple's API Design Guidelines for clarity at the point of use.

Element Convention Example
Types (Class, Struct, Enum) UpperCamelCase UserProfileView, NetworkService
Variables & Functions lowerCamelCase var userName: String
func fetchUserData()
Constants (Global) lowerCamelCase let maxRetryCount = 3
Booleans Prefixed with is, has, did var isUserLoggedIn: Bool
@IBOutlet (UIKit) lowerCamelCase @IBOutlet var userNameLabel: UILabel
@IBAction (UIKit) lowerCamelCase (verb first) @IBAction func didTapSubmitButton(_ sender: Any)

Reference: Apple's API Design Guidelines

5. Code Formatting & Style

  • Indentation: 4 spaces (or 2 if team agrees, but be consistent).
  • Maximum line length: 120 characters (enforced by SwiftLint).
  • Avoid unused imports, variables, or commented-out code.
  • Add Swift-DocC comments (///) for all public classes, methods, and complex logic.
  • Use let instead of var wherever possible for immutability.
  • Use final on classes not intended for subclassing to improve performance.

Learn more: Swift-DocC Documentation

6. UI/UX & Resource Management

  • Use SwiftUI Stacks/Grids or Auto Layout (for UIKit) for flexible designs.
  • No hardcoding.
    • Text: Use Localizable.strings for all user-facing text.
    • Colors/Images: Use the Assets.xcassets catalog.
  • Use private for@IBOutlet and @IBAction to encapsulate view logic.
  • Follow accessibility guidelines (e.g., accessibilityLabel, dynamic type support).

Learn more: Using the Asset Catalog

7. Networking & Data Handling

  • Use native URLSession with async/await for all REST APIs.
    • Combine is acceptable for reactive streams.
    • Alamofire is acceptable for complex networking needs if approved.
  • Use SwiftData (preferred for new projects) or Core Data for local database storage.
  • Parse JSON using the Codable protocol.
  • Handle API responses using Swift's Result type or async throws.
  • Avoid network calls on the main thread. Use Task or await MainActor.run to update UI.

Learn more: Fetching data with URLSession and async/await

8. Error Handling & Logging

  • Use Swift's error handling (do-try-catch, throws) for failable operations.
  • Never use print() for logging.
  • Use Apple's OSLog (Logger) framework for all logging.
  • Swift
import OSLog
let logger = Logger(subsystem: "com.yourapp.feature", category:
"ViewModel")
logger.debug("Loading user profile...")
logger.error("Error loading user profile:
\(error.localizedDescription)")
  • OSLog logs are automatically managed (not shown in release builds) and viewable in the Console app.

Learn more: Logging in Swift with OSLog

9. Security & Performance

  • Never store sensitive data (tokens, passwords, PII) in UserDefaults. Use the Keychain services.
  • Use [weak self] in closures to prevent retain cycles (memory leaks).
  • Set "Optimization Level" to -O (Fastest, Smallest) in Release builds.
  • Use Instruments (Leaks, Time Profiler) to find and fix performance issues.

Learn more: Storing Data in the Keychain

10. Testing

  • Write XCTest Unit Tests for ViewModels, business logic, and utility functions.
  • Write XCTest UI Tests for critical user flows.
  • Maintain at least 70% test coverage for core modules.
  • Use protocol-based mocking and dependency injection to make code testable.

Learn more: Testing with XCTest

11. Automation & CI/CD Integration

  • Integrate static analysis tools:
    • SwiftLint: Enforces formatting and style rules.
    • SwiftFormat: (Optional) Automatically formats code.
  • Use Xcode's built-in "Analyze" tool to find potential bugs and leaks.
  • CI/CD (e.g.,** Xcode Cloud**, GitHub Actions) should run XCTest and SwiftLint and fail the build on violations.

Learn more: Integrating SwiftLint with Xcode

12. References