Swift logoSwift INTERMEDIATE

Swift

Comprehensive Swift reference for iOS and macOS development

12 min read

Getting Started

Swift basics and setup

Variables & Constants

Declaration and initialization

javascript
💡 Use `let` by default, only use `var` when you need mutability
⚡ Swift has strong type inference - explicit types often unnecessary
📌 Constants can be set once and only once, even after declaration
🟢 Computed properties calculate their value each time they are accessed

Basic Types

Swift fundamental data types

javascript
💡 Int is 64-bit on 64-bit platforms, 32-bit on 32-bit platforms
⚡ String interpolation with \() is more efficient than concatenation
📌 Tuples are useful for returning multiple values from functions
🟢 Use type aliases to make complex types more readable

Optionals

Handling nil values safely

Optional Basics

Declaration and unwrapping

javascript
💡 Prefer optional binding over force unwrapping to avoid crashes
⚡ Use guard for early returns when dealing with optionals
📌 Nil coalescing (??) provides a clean way to supply default values
🟢 Optional chaining (?.) safely accesses properties and methods

Collections

Arrays, Sets, and Dictionaries

Arrays

Ordered collections of values

javascript
💡 Arrays are value types - they are copied when assigned
⚡ Use reserveCapacity for better performance with large arrays
📌 ArraySlice shares indices with original array
🟢 Higher-order functions (map, filter, reduce) enable functional programming

Dictionaries

Key-value pair collections

javascript
💡 Dictionary access returns optionals since keys might not exist
⚡ Use default parameter to avoid nil checking
📌 merge() is powerful for combining dictionaries with custom logic
🟢 Dictionary(grouping:by:) creates dictionaries from sequences

Functions & Closures

Function definitions and closures

Functions

Function declaration and parameters

javascript
💡 Use argument labels for clarity at call sites
⚡ Inout parameters allow functions to modify values
📌 Functions are first-class types in Swift
🟢 @discardableResult suppresses unused return value warnings

Closures

Anonymous functions and capturing

javascript
💡 Trailing closure syntax improves readability
⚡ @escaping is required when closure outlives function
📌 Closures capture values by reference by default
🟢 Swift provides progressive syntax shortcuts for closures

Structs & Classes

Value and reference types

Structs

Value types with properties and methods

javascript
💡 Structs are value types - copied when assigned
⚡ Use mutating keyword to modify struct properties
📌 Structs get memberwise initializers automatically
🟢 Prefer structs over classes for simple data models

Classes

Reference types with inheritance

javascript
💡 Classes are reference types - variables share same instance
⚡ Use final to prevent inheritance or overriding
📌 Deinitializers run when instances are deallocated
🟢 Type casting with as? safely attempts downcasting

Enums

Enumerations with associated values

Basic Enums

Simple and raw value enumerations

javascript
💡 Enums define a common type for related values
⚡ CaseIterable provides automatic allCases array
📌 Raw values must be literals and unique
🟢 Enums can have computed properties and methods

Associated Values

Enums with different value types

javascript
💡 Associated values can be different types for each case
⚡ Use where clauses for additional pattern matching
📌 indirect enables recursive enum definitions
🟢 Associated values are extracted with let/var binding

Protocols

Protocol definitions and conformance

Protocol Basics

Defining and adopting protocols

javascript
💡 Protocols define a blueprint of requirements
⚡ Protocol extensions provide default implementations
📌 Associated types make protocols generic
🟢 Use & for protocol composition

Error Handling

Throwing and catching errors

Error Basics

Defining and throwing errors

javascript
💡 Errors must conform to Error protocol
⚡ try? converts throwing results to optionals
📌 defer executes code when scope exits
🟢 Use specific error cases for clear error handling

Concurrency

Async/await and actors

Async/Await

Modern Swift concurrency

javascript
💡 async/await makes asynchronous code look synchronous
⚡ async let enables parallel execution
📌 Task groups handle dynamic concurrency
🟢 @MainActor ensures UI updates on main thread

Actors

Thread-safe reference types

javascript
💡 Actors provide thread-safe access to mutable state
⚡ All actor methods are implicitly async
📌 Sendable ensures types are safe to share across threads
🟢 Use actors to prevent data races

Extensions

Extending existing types with new functionality

Type Extensions

Adding functionality to existing types

javascript
💡 Extensions can add computed properties but not stored properties
⚡ Use extensions to organize code into logical groups
📌 Extensions can add protocol conformance retroactively
🟢 Extensions work on all types: classes, structs, enums, protocols

Conditional Extensions

Extensions with generic constraints

javascript
💡 Generic where clauses enable powerful conditional extensions
⚡ Protocol extensions provide default implementations
📌 Conditional conformance adds protocol only when constraints are met
🟢 Use constraints to add methods only to specific generic types

Generics (Advanced)

Generic programming and type constraints

Generic Constraints

Advanced generic type relationships

javascript
💡 Multiple constraints can be combined with &
⚡ Associated types with constraints enable powerful abstractions
📌 Conditional methods appear only when constraints are satisfied
🟢 Opaque types (some) hide implementation details while preserving type

Memory Management

ARC, weak/unowned references, and memory optimization

Reference Cycles

Breaking retain cycles with weak and unowned

javascript
💡 Use weak for optional references that might become nil
⚡ Use unowned when reference will never be nil during use
📌 Always use capture lists in closures to prevent retain cycles
🟢 Check for memory leaks with Instruments

Access Control

Controlling visibility and access to code

Access Levels

Five levels of access control

javascript
💡 Default access level is internal within a module
⚡ Use private(set) for read-only properties outside the type
📌 Access level cannot be more permissive than its enclosing type
🟢 Start with most restrictive access and open up as needed

Type Casting

Type checking, casting, and Any/AnyObject

Type Checking & Casting

is, as, as?, as! operators

javascript
💡 Use is for type checking, as? for safe casting
⚡ Avoid as! force casting - it crashes if cast fails
📌 Any can hold any type, AnyObject only class instances
🟢 Swift automatically bridges to Objective-C types when needed

Property Wrappers

Encapsulating property storage logic

Creating Property Wrappers

Custom property wrapper implementation

javascript
💡 Property wrappers encapsulate repetitive property logic
⚡ Use $ to access the projected value of a property wrapper
📌 SwiftUI heavily uses property wrappers (@State, @Binding, etc.)
🟢 Property wrappers can have init parameters for configuration

Operators

Custom operators and operator overloading

Custom Operators

Defining and implementing custom operators

javascript
💡 Operator overloading must match existing operator signatures
⚡ Custom operators need explicit precedence and associativity
📌 Use ~= to enable pattern matching in switch statements
🟢 Keep custom operators simple and intuitive

Attributes

Swift attributes for compile-time configuration

Common Attributes

Built-in Swift attributes

javascript
💡 @available helps manage API compatibility across OS versions
⚡ @objc enables Objective-C interoperability
📌 @escaping marks closures that outlive the function
🟢 @main designates the app entry point

Initialization

Initialization rules and patterns

Initialization Patterns

Designated, convenience, and failable initializers

javascript
💡 Designated initializers must initialize all properties
⚡ Convenience initializers must call another initializer
📌 Failable initializers return nil on failure
🟢 Use lazy properties for expensive initialization

Subscripts

Custom subscript syntax for types

Subscript Implementation

Adding subscript access to custom types

javascript
💡 Subscripts can have multiple parameters
⚡ Use subscripts for natural index-based access
📌 Type subscripts use static keyword
🟢 Subscripts can be generic and have default parameters

Result Builders

Building DSLs with result builders

Result Builder Basics

Creating domain-specific languages

javascript
💡 Result builders enable SwiftUI-style declarative syntax
⚡ buildBlock is the core method that combines components
📌 buildIf and buildEither handle conditionals
🟢 Use @resultBuilder to create intuitive DSLs