Swift Standards
Swift Standards
Section titled “Swift Standards”1. Package Management
Section titled “1. Package Management”- Tool: Swift Package Manager (SPM).
Package.swiftfor dependencies. - Version: Swift 5.9+ (use latest stable).
- Dependencies: Declare in
Package.swift. Pin versions or use ranges.
2. Code Style
Section titled “2. Code Style”- Formatter:
swiftformatorswift-format. Line length 120. - Linter:
swiftlint. Configure via.swiftlint.yml. - Type Checker: Swift compiler strict warnings. Enable all warnings as errors in release.
Package.swift Example
Section titled “Package.swift Example”import PackageDescription
let package = Package( name: "ProjectName", platforms: [.macOS(.v13), .iOS(.v16)], dependencies: [ .package(url: "https://github.com/apple/swift-log", from: "1.0.0") ])3. Naming Conventions
Section titled “3. Naming Conventions”- Types/Protocols:
PascalCase - Functions/Variables:
camelCase - Constants:
camelCase(useletfor immutability) - Private:
privateaccess control (no underscore prefix) - Files:
PascalCase.swiftmatching primary type name
4. Project Structure
Section titled “4. Project Structure”Sources/├── Domain/│ ├── Entities/│ └── ValueObjects/├── Application/│ ├── UseCases/│ └── Interfaces/└── Infrastructure/ └── Repositories/Tests/└── [Mirror Sources structure]5. Language Features
Section titled “5. Language Features”- Immutability: Prefer
letovervar. Usestructfor value types. - Optionals: Use
Optional<T>(T?) for nullable values. Avoid force unwrapping (!). - Protocols: Use protocols for interfaces. Prefer protocol-oriented design.
- Generics: Use generics for reusable code. Use
whereclauses for constraints.
Example
Section titled “Example”struct Email: Equatable { let value: String
init(_ value: String) throws { guard value.contains("@") && value.contains(".") else { throw InvalidEmailError(value) } self.value = value }}
enum Result<T> { case success(T) case failure(Error)}6. Error Handling
Section titled “6. Error Handling”- Errors: Use
Errorprotocol. Preferenumfor typed errors. - Throwing: Use
throwsfor functions that can fail. Usetry?ordo-catch. - Result Type: Use
Result<T, Error>for functional error handling.
enum DomainError: Error { case invalidEmail(String) case userNotFound(String)
var localizedDescription: String { switch self { case .invalidEmail(let email): return "Invalid email: \(email)" case .userNotFound(let id): return "User not found: \(id)" } }}7. Testing
Section titled “7. Testing”- Framework:
XCTest. UseXCTAssert*functions. - Mocking: Use protocols for testability. Create test doubles manually or use
Mockingbird. - Coverage: Enable code coverage in Xcode. 95% is the absolute minimum for any module. Target 100% for domain, 95%+ for application and infrastructure.
Test Structure
Section titled “Test Structure”import XCTest@testable import Domain
final class UserTests: XCTestCase { func testShouldCreateUserWithValidEmail() throws { // Given let email = try Email("test@example.com")
// When let user = User(email: email, name: "Test User")
// Then XCTAssertEqual(user.email.value, "test@example.com") }}8. Concurrency
Section titled “8. Concurrency”- Async/Await: Use
async/awaitfor concurrent operations (Swift 5.5+). - Actors: Use
actorfor thread-safe mutable state. - Tasks: Use
TaskandTaskGroupfor structured concurrency.
actor UserRepository { private var users: [String: User] = [:]
func findById(_ id: String) async -> User? { return users[id] }
func save(_ user: User) async { users[user.id] = user }}9. Memory Management
Section titled “9. Memory Management”- ARC: Automatic Reference Counting. Avoid retain cycles with
weak/unowned. - Closures: Use
[weak self]or[unowned self]in closures to prevent cycles. - Value Types: Prefer
structoverclasswhen possible.
10. Dependencies
Section titled “10. Dependencies”Common Libraries
Section titled “Common Libraries”- Networking:
URLSession(native),Alamofirefor complex needs - JSON:
Codableprotocol (native),SwiftyJSONfor dynamic parsing - Logging:
swift-log(server-side),os.log(Apple platforms)
11. Documentation
Section titled “11. Documentation”- Doc Comments: Use triple-slash (
///) for documentation. Supports Markdown. - Format: Use
- Parameter,- Returns,- Throwstags.
/// Creates a new user with validated email address.////// - Parameter email: Valid email address (must match RFC 5322)/// - Parameter name: User's full name (non-null, non-empty)/// - Returns: New User entity instance/// - Throws: `InvalidEmailError` if email format is invalidfunc createUser(email: String, name: String) throws -> User { // Implementation}12. Platform-Specific
Section titled “12. Platform-Specific”- iOS/macOS: Follow Apple’s Human Interface Guidelines.
- Server-Side: Use Vapor or SwiftNIO for HTTP servers.
- Cross-Platform: Use
#if os()for platform-specific code.