Swift Conventions & Best Practices
Swift Conventions & Best Practices
Naming Conventions
Files: PascalCase.swift
UserViewModel.swift
NetworkClient.swift
SessionManager.swift
Classes/Structs/Enums: PascalCase
class UserViewModel
struct User
enum NetworkError
Variables/Functions: camelCase
var userName: String
func fetchUserData()
Constants:
// Instance constants: camelCase
let maxRetries = 3
// Static/Global constants: SCREAMING_SNAKE_CASE or camelCase
static let BASE_URL = "https://api.example.com"
static let defaultTimeout: TimeInterval = 30
Protocols: Descriptive names, often ending with Protocol
protocol NetworkClientProtocol { }
protocol UserServiceProtocol { }
File Structure
//
// FileName.swift
// ProjectName
//
import Foundation
import Combine
// MARK: - Main Type Definition
class/struct/enum TypeName {
// MARK: - Properties
// MARK: - Initialization
// MARK: - Public Methods
// MARK: - Private Methods
}
// MARK: - Extensions
extension TypeName {
// Extension content
}
// MARK: - Protocol Conformance
extension TypeName: ProtocolName {
// Protocol implementation
}
Code Organization
Property Order:
- Type properties (static)
- Instance properties (stored)
- Computed properties
- Property observers
Method Order:
- Lifecycle methods (init, deinit)
- Public methods
- Private methods
SwiftLint Key Rules
Line Length: 120 characters max
// ✅ Good
let user = User(id: id, name: name, email: email)
// ❌ Too long
let user = User(id: userId, name: userName, email: userEmail, phoneNumber: userPhoneNumber, address: userAddress)
Force Unwrapping: Avoid ! except in tests or guaranteed scenarios
// ❌ Dangerous
let name = user.name!
// ✅ Safe
guard let name = user.name else { return }
Trailing Closures: Use for single trailing closure
// ✅ Good
items.map { $0.id }
// ❌ Avoid
items.map({ $0.id })
Swift 5 Modern Features
Async/Await:
func fetchUser(id: String) async throws -> User {
let request = UserAPI.fetchUser(id: id)
return try await networkClient.request(request)
}
Result Type:
func fetchUser(id: String) async -> Result<User, NetworkError> {
do {
let user = try await performFetch(id)
return .success(user)
} catch {
return .failure(.networkError(error))
}
}
Property Wrappers:
@Published var items: [Item] = []
@State private var isPresented = false
@Binding var selectedItem: Item?
Access Control
// Public: API surface
public class NetworkClient { }
// Internal: Default, module-wide
class UserViewModel { }
// Private: File-scoped
private func helper() { }
// Private(set): Read public, write private
private(set) var count: Int = 0
Error Handling
// Custom error enum
enum NetworkError: Error {
case invalidURL
case noData
case decodingFailed(Error)
}
// Throwing function
func fetchData() throws -> Data {
guard let url = URL(string: urlString) else {
throw NetworkError.invalidURL
}
return try Data(contentsOf: url)
}
// Async throws
func fetchUser() async throws -> User {
try await networkClient.request(.fetchUser)
}
Protocol-Oriented Programming
// Protocol definition
protocol UserServiceProtocol {
func fetchUser(id: String) async -> Result<User, NetworkError>
}
// Implementation
final class UserService: UserServiceProtocol {
func fetchUser(id: String) async -> Result<User, NetworkError> {
// Implementation
}
}
// Dependency injection
class UserViewModel {
private let userService: UserServiceProtocol
init(userService: UserServiceProtocol = UserService()) {
self.userService = userService
}
}
More from kaakati/rails-enterprise-dev
flutter conventions & best practices
Dart 3.x and Flutter 3.x conventions, naming patterns, code organization, null safety, and async/await best practices
55getx state management patterns
GetX controllers, reactive state, dependency injection, bindings, navigation, and best practices
52tailadmin ui patterns
TailAdmin dashboard UI framework patterns and Tailwind CSS classes. ALWAYS use this skill when: (1) Building any dashboard or admin panel interface, (2) Creating data tables, cards, charts, or metrics displays, (3) Implementing forms, buttons, alerts, or modals, (4) Building navigation (sidebar, header, breadcrumbs), (5) Any UI work that should follow TailAdmin design. This skill REQUIRES fetching from the official GitHub repository to ensure accurate class usage - NEVER invent classes.
39mvvm-architecture
Expert MVVM decisions for iOS/tvOS: choosing between ViewModel patterns (state enum vs published properties vs Combine), service layer boundaries, dependency injection strategies, and testing approaches. Use when designing ViewModel architecture, debugging data flow issues, or deciding where business logic belongs. Trigger keywords: MVVM, ViewModel, ObservableObject, @StateObject, service layer, dependency injection, unit test, mock, architecture
36rails localization (i18n) - english & arabic
Comprehensive internationalization skill for Ruby on Rails applications with proper English and Arabic translations, RTL support, pluralization rules, date/time formatting, and culturally appropriate content adaptation.
34rspec testing patterns
Complete guide to testing Ruby on Rails applications with RSpec. Use this skill when writing unit tests, integration tests, system tests, or when setting up test infrastructure including factories, shared examples, and mocking strategies.
31