Master Swift with this all-in-one reference guide covering 25 essential topics: from basic syntax, variables, and control flow to advanced concepts like generics, concurrency, property wrappers, and result builders. Includes practical code examples for collections, protocols, error handling, memory management, and SwiftUI. Perfect for beginners learning iOS/macOS development and experienced developers needing quick syntax recall. Features async/await, actors, closures, and pattern matching. Your go-to Swift resource for faster, more efficient coding.
- Basic Syntax
- Variables and Constants
- Data Types
- Operators
- Control Flow
- Functions
- Closures
- Optionals
- Collections
- Strings
- Classes and Structures
- Properties
- Methods
- Inheritance
- Protocols
- Extensions
- Generics
- Error Handling
- Concurrency
- Memory Management
- Access Control
- Pattern Matching
- Type Casting
- Property Wrappers
- Result Builders
// Comments
// Single line comment
/* Multi-line
comment */
// Print to console
print("Hello, World!")
// String interpolation
let name = "John"
print("Hello, \(name)")
// Semicolons are optional
let a = 5; let b = 10 // Can use to separate statements
// Module import
import Foundation
import UIKit// Constants (immutable)
let constant = 42
let pi = 3.14159
// Variables (mutable)
var variable = 10
variable = 20
// Type annotations
var explicitString: String = "Hello"
var explicitInt: Int = 42
var explicitDouble: Double = 3.14
var explicitBool: Bool = true
// Multiple declarations
var x = 1, y = 2, z = 3
let a = 1, b = 2, c = 3
// Type inference
let inferredString = "Type is String"
let inferredInt = 42
let inferredDouble = 3.14// Integers
let integer: Int = 42
let int8: Int8 = 127
let int16: Int16 = 32767
let int32: Int32 = 2147483647
let int64: Int64 = 9223372036854775807
let unsignedInt: UInt = 42
// Floating-point numbers
let double: Double = 3.14159265359 // 64-bit (preferred)
let float: Float = 3.14 // 32-bit
// Boolean
let bool: Bool = true
// Character
let character: Character = "A"
let emoji: Character = "😀"
// String
let string: String = "Hello, World!"
// Tuples
let tuple = (1, "Hello", true)
let namedTuple = (code: 200, message: "OK")
let (statusCode, statusMessage) = namedTuple
let (_, justMessage) = namedTuple // Ignore first element
// Type aliases
typealias AudioSample = UInt16
var sample: AudioSample = 45
// Numeric literals
let decimal = 17
let binary = 0b10001 // 17
let octal = 0o21 // 17
let hexadecimal = 0x11 // 17
let scientific = 1.25e2 // 125.0
let padded = 000123 // 123
let formatted = 1_000_000 // 1000000// Arithmetic operators
let sum = 5 + 3 // 8
let difference = 10 - 3 // 7
let product = 4 * 2 // 8
let quotient = 10 / 3 // 3
let remainder = 10 % 3 // 1
let negation = -5 // -5
// Compound assignment operators
var count = 5
count += 2 // count = 7
count -= 3 // count = 4
count *= 2 // count = 8
count /= 4 // count = 2
// Comparison operators
let isEqual = 5 == 5 // true
let isNotEqual = 5 != 3 // true
let isGreater = 10 > 5 // true
let isLess = 3 < 7 // true
let isGreaterOrEqual = 10 >= 10 // true
let isLessOrEqual = 5 <= 3 // false
// Logical operators
let and = true && false // false
let or = true || false // true
let not = !true // false
// Ternary conditional operator
let value = 10
let result = value > 5 ? "Greater" : "Less"
// Nil-coalescing operator
let optionalName: String? = nil
let name = optionalName ?? "Default Name"
// Range operators
let closedRange = 1...5 // 1,2,3,4,5
let halfOpenRange = 1..<5 // 1,2,3,4
let oneSidedRange = ...5
let oneSidedRange2 = 2...
let array = [1, 2, 3, 4, 5]
let slice = array[2...] // 3,4,5
// Identity operators (for reference types)
class MyClass {}
let object1 = MyClass()
let object2 = object1
let isSameObject = object1 === object2 // true
let isNotSameObject = object1 !== MyClass() // true// If statement
if condition {
// code
} else if anotherCondition {
// code
} else {
// code
}
// Switch statement (no break needed, exhaustive)
switch value {
case 1:
print("One")
case 2, 3:
print("Two or Three")
case 4...10:
print("Between 4 and 10")
default:
print("Other")
}
// Switch where clause
switch number {
case let x where x % 2 == 0:
print("\(x) is even")
default:
print("Odd")
}
// For-in loops
for i in 0...5 {
print(i)
}
let numbers = [1, 2, 3, 4, 5]
for number in numbers {
print(number)
}
let dict = ["a": 1, "b": 2]
for (key, value) in dict {
print("\(key): \(value)")
}
// Stride
for i in stride(from: 0, to: 10, by: 2) {
print(i) // 0, 2, 4, 6, 8
}
for i in stride(from: 0, through: 10, by: 2) {
print(i) // 0, 2, 4, 6, 8, 10
}
// While loop
while condition {
// code
}
// Repeat-while loop
repeat {
// code
} while condition
// Control transfer statements
continue // Skip current iteration
break // Exit loop
fallthrough // Fall through to next switch case
return // Exit function
throw // Throw error
// Labeled statements
outerLoop: for i in 1...3 {
for j in 1...3 {
if i * j == 6 {
break outerLoop
}
}
}
// Guard statement
guard condition else {
// Exit early (must transfer control)
return
}// Basic function
func greet(person: String) -> String {
return "Hello, \(person)!"
}
// Multiple parameters
func multiply(a: Int, b: Int) -> Int {
return a * b
}
// No return value
func sayHello() {
print("Hello!")
}
// Or
func sayHi() -> Void {
print("Hi!")
}
// Or
func sayHey() -> () {
print("Hey!")
}
// Multiple return values (tuple)
func minMax(array: [Int]) -> (min: Int, max: Int)? {
guard let first = array.first else { return nil }
var currentMin = first
var currentMax = first
for value in array {
if value < currentMin {
currentMin = value
}
if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
// Argument labels
func greet(person name: String, from hometown: String) {
print("Hello \(name)! Glad you could visit from \(hometown).")
}
greet(person: "John", from: "New York")
// Omitting argument labels
func add(_ a: Int, _ b: Int) -> Int {
return a + b
}
let sum = add(5, 3)
// Default parameter values
func greet(person: String, politely: Bool = true) -> String {
if politely {
return "Hello, \(person), how are you?"
} else {
return "Hey, \(person)!"
}
}
// Variadic parameters
func sum(_ numbers: Int...) -> Int {
return numbers.reduce(0, +)
}
let total = sum(1, 2, 3, 4, 5) // 15
// In-out parameters
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temp = a
a = b
b = temp
}
var x = 5, y = 10
swapTwoInts(&x, &y)
// Function types
let mathFunction: (Int, Int) -> Int = add
var anotherMathFunction = multiply
// Nested functions
func outerFunction() -> Int {
func innerFunction() -> Int {
return 42
}
return innerFunction()
}// Basic closure syntax
{ (parameters) -> ReturnType in
statements
}
// Closure examples
let greet = { (name: String) -> String in
return "Hello, \(name)!"
}
// Shorthand argument names
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map { $0 * 2 }
// Trailing closure syntax
numbers.map { $0 * 2 }
// Capturing values
func makeIncrementer(incrementAmount: Int) -> () -> Int {
var total = 0
let incrementer: () -> Int = {
total += incrementAmount
return total
}
return incrementer
}
// Escaping closures
var completionHandlers: [() -> Void] = []
func functionWithEscapingClosure(completion: @escaping () -> Void) {
completionHandlers.append(completion)
}
// Autoclosures
func serve(customer customerProvider: @autoclosure () -> String) {
print("Now serving \(customerProvider())!")
}
serve(customer: "John")
// Common closure methods
let sorted = numbers.sorted(by: { $0 > $1 })
let filtered = numbers.filter { $0 > 3 }
let mapped = numbers.map { String($0) }
let reduced = numbers.reduce(0, +)
let flatMapped = numbers.flatMap { [$0, $0 * 2] }
let compactMapped = ["1", "2", "three"].compactMap { Int($0) } // [1, 2]// Optional declaration
var optionalString: String? = "Hello"
var optionalInt: Int?
var implicitOptional: String! = "Implicitly unwrapped"
// Unwrapping methods
// 1. Force unwrapping (unsafe)
let forced = optionalString!
// 2. Optional binding (if let)
if let unwrapped = optionalString {
print(unwrapped)
}
// 3. Optional binding (guard let)
func process(string: String?) {
guard let unwrapped = string else {
return
}
print(unwrapped)
}
// 4. Nil-coalescing operator
let value = optionalInt ?? 0
// 5. Optional chaining
class Person {
var residence: Residence?
}
class Residence {
var address: Address?
}
class Address {
var street: String?
}
let person = Person()
let street = person.residence?.address?.street
// Optional chaining with methods
class Room {
func printNumberOfRooms() {
print("5 rooms")
}
}
let room: Room? = Room()
room?.printNumberOfRooms()
// Optional map and flatMap
let optionalNumber: Int? = 5
let mapped = optionalNumber.map { $0 * 2 } // Optional(10)
let flatMapped = optionalNumber.flatMap { $0 > 3 ? $0 : nil } // Optional(5)// Arrays
var fruits = ["Apple", "Banana", "Orange"]
let emptyArray: [String] = []
let emptyArray2 = [Int]()
// Array operations
fruits.append("Mango")
fruits += ["Grapes", "Pineapple"]
fruits.insert("Strawberry", at: 0)
fruits.remove(at: 1)
fruits.removeLast()
fruits[0] = "Green Apple"
let firstFruit = fruits.first
let lastFruit = fruits.last
let count = fruits.count
let isEmpty = fruits.isEmpty
let contains = fruits.contains("Apple")
// Array iteration
for fruit in fruits {
print(fruit)
}
for (index, fruit) in fruits.enumerated() {
print("\(index): \(fruit)")
}
// Useful array methods
let sorted = fruits.sorted()
let reversed = fruits.reversed()
let shuffled = fruits.shuffled()
let randomElement = fruits.randomElement()
let slice = fruits[1...3]
// Sets
var set: Set = [1, 2, 3, 4, 5]
set.insert(6)
set.remove(2)
let containsElement = set.contains(3)
// Set operations
let set1: Set = [1, 2, 3, 4]
let set2: Set = [3, 4, 5, 6]
let union = set1.union(set2) // [1, 2, 3, 4, 5, 6]
let intersection = set1.intersection(set2) // [3, 4]
let difference = set1.subtracting(set2) // [1, 2]
let symmetricDifference = set1.symmetricDifference(set2) // [1, 2, 5, 6]
let isSubset = set1.isSubset(of: set2)
let isSuperset = set1.isSuperset(of: set2)
let isDisjoint = set1.isDisjoint(with: set2)
// Dictionaries
var scores: [String: Int] = ["Alice": 95, "Bob": 87, "Charlie": 78]
let emptyDict: [String: Int] = [:]
let emptyDict2 = [String: Int]()
// Dictionary operations
scores["David"] = 92
scores["Alice"] = 100
scores.updateValue(88, forKey: "Bob")
scores.removeValue(forKey: "Charlie")
scores["Charlie"] = nil // Also removes value
// Dictionary access
let aliceScore = scores["Alice"] // Optional(100)
let aliceValue = scores["Alice", default: 0] // 100
let count2 = scores.count
let keys = scores.keys
let values = scores.values
// Dictionary iteration
for (name, score) in scores {
print("\(name): \(score)")
}
// Useful dictionary methods
let mappedValues = scores.mapValues { $0 + 5 }
let grouped = Dictionary(grouping: [1, 2, 3, 4, 5]) { $0 % 2 == 0 ? "even" : "odd" }
let merged = scores.merging(["Eve": 85]) { (current, _) in current }// String creation
let string = "Hello, World!"
let multiline = """
This is a
multiline
string.
"""
// String properties
let count3 = string.count
let isEmpty2 = string.isEmpty
let lowercase = string.lowercased()
let uppercase = string.uppercased()
let capitalized = string.capitalized
// String interpolation
let name2 = "John"
let age = 30
let message = "\(name2) is \(age) years old"
// Character access
let firstChar = string.first // Optional("H")
let lastChar = string.last // Optional("!")
let startIndex = string.startIndex
let endIndex = string.endIndex
let index = string.index(string.startIndex, offsetBy: 7)
let char = string[index] // "W"
// Substrings
let substring = string.prefix(5) // "Hello"
let suffix = string.suffix(6) // "World!"
let dropFirst = string.dropFirst(7) // "World!"
let dropLast = string.dropLast(1) // "Hello, World"
// Range-based substring
let range = string.index(string.startIndex, offsetBy: 7)..<string.endIndex
let sub = string[range] // "World!"
// String modification
var greeting = "Hello"
greeting.append(", World!")
greeting += " How are you?"
greeting.insert("!", at: greeting.startIndex)
greeting.insert(contentsOf: "Hey, ", at: greeting.startIndex)
greeting.remove(at: greeting.startIndex)
// String comparison
let equal = "hello" == "hello"
let hasPrefix = string.hasPrefix("Hello")
let hasSuffix = string.hasSuffix("!")
let contains2 = string.contains("World")
// String splitting
let words = "Hello, World, Swift".components(separatedBy: ", ")
let words2 = "Hello World Swift".split(separator: " ")
// String indices
for index in string.indices {
print(string[index])
}
// Unicode
let emoji2 = "😀"
for scalar in string.unicodeScalars {
print(scalar.value)
}// Structure (value type)
struct Point {
var x: Double
var y: Double
init(x: Double, y: Double) {
self.x = x
self.y = y
}
func distance(from point: Point) -> Double {
let dx = x - point.x
let dy = y - point.y
return sqrt(dx * dx + dy * dy)
}
}
// Class (reference type)
class Vehicle {
var speed: Double = 0
var description: String {
return "Traveling at \(speed) mph"
}
func makeNoise() {
// Do nothing
}
}
// Initialization
let point = Point(x: 10, y: 20)
let vehicle = Vehicle()
// Memberwise initializer (auto-generated for structs)
let defaultPoint = Point(x: 0, y: 0)
// Designated vs Convenience initializers
class Food {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[Unnamed]")
}
}
// Failable initializers
struct Animal {
let species: String
init?(species: String) {
if species.isEmpty { return nil }
self.species = species
}
}
// Required initializers
class SomeClass {
required init() {
// Must be implemented by subclasses
}
}
// Deinitializers (classes only)
class FileManager {
var filePath: String
init(path: String) {
self.filePath = path
}
deinit {
print("Cleaning up \(filePath)")
}
}// Stored properties
struct Person {
var firstName: String
var lastName: String
let id: Int // Constant stored property
}
// Computed properties
struct Rectangle {
var width: Double
var height: Double
var area: Double {
get {
return width * height
}
}
var perimeter: Double {
return 2 * (width + height)
}
}
// Property observers
class StepCounter {
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
print("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
print("Added \(totalSteps - oldValue) steps")
}
}
}
}
// Lazy stored properties
class DataImporter {
var filename = "data.txt"
}
class DataManager {
lazy var importer = DataImporter()
var data: [String] = []
}
// Type properties
struct SomeStructure {
static var storedTypeProperty = "Some value"
static var computedTypeProperty: Int {
return 42
}
}
class SomeClass2 {
static var storedTypeProperty = "Some value"
class var overrideableComputedTypeProperty: Int {
return 42
}
}
// Accessing type properties
let value1 = SomeStructure.storedTypeProperty
SomeStructure.storedTypeProperty = "New value"// Instance methods
class Counter {
var count = 0
func increment() {
count += 1
}
func increment(by amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
let counter = Counter()
counter.increment()
counter.increment(by: 5)
// Self property
struct Point2 {
var x = 0.0, y = 0.0
func isToTheRight(of x: Double) -> Bool {
return self.x > x // self disambiguates
}
}
// Mutating methods (structs and enums)
struct Point3 {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
mutating func moveTo(x: Double, y: Double) {
self = Point3(x: x, y: y)
}
}
// Type methods
class SomeClass3 {
class func someTypeMethod() {
print("Type method called")
}
static func anotherTypeMethod() {
print("Static type method")
}
}
SomeClass3.someTypeMethod()// Base class
class Vehicle2 {
var currentSpeed = 0.0
var description: String {
return "Traveling at \(currentSpeed) mph"
}
func makeNoise() {
print("Vehicle noise")
}
}
// Subclass
class Bicycle: Vehicle2 {
var hasBasket = false
override func makeNoise() {
print("Ring ring")
}
override var description: String {
return super.description + " on a bicycle"
}
}
// Preventing overrides
final class FinalClass {
// Cannot be subclassed
}
class Parent {
final func cannotOverride() {
// Cannot be overridden
}
}
// Required initializers
class Vehicle3 {
var speed: Double
required init(speed: Double) {
self.speed = speed
}
}
class Car: Vehicle3 {
required init(speed: Double) {
super.init(speed: speed)
}
}// Protocol definition
protocol FullyNamed {
var fullName: String { get }
func introduce() -> String
}
// Protocol adoption
struct Person2: FullyNamed {
var fullName: String
func introduce() -> String {
return "Hi, I'm \(fullName)"
}
}
// Protocol with mutating methods
protocol Togglable {
mutating func toggle()
}
enum OnOffSwitch: Togglable {
case on, off
mutating func toggle() {
switch self {
case .on:
self = .off
case .off:
self = .on
}
}
}
// Protocol inheritance
protocol TextRepresentable {
var textualDescription: String { get }
}
protocol PrettyTextRepresentable: TextRepresentable {
var prettyTextualDescription: String { get }
}
// Class-only protocols
protocol ClassOnly: AnyObject {
// Only classes can adopt this
}
// Protocol composition
protocol Named {
var name: String { get }
}
protocol Aged {
var age: Int { get }
}
func wishHappyBirthday(to celebrator: Named & Aged) {
print("Happy birthday, \(celebrator.name), you're \(celebrator.age)!")
}
// Optional protocol requirements
@objc protocol CounterDataSource {
@objc optional func increment(forCount count: Int) -> Int
@objc optional var fixedIncrement: Int { get }
}
// Protocol extensions
extension FullyNamed {
func introduce() -> String {
return "Hello, I'm \(fullName)"
}
}
// Conditional conformance
extension Array: TextRepresentable where Element: TextRepresentable {
var textualDescription: String {
let itemsAsText = self.map { $0.textualDescription }
return "[" + itemsAsText.joined(separator: ", ") + "]"
}
}// Extension syntax
extension SomeType {
// Add functionality here
}
// Computed properties
extension Double {
var km: Double { return self * 1000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1000.0 }
}
let distance = 5.km // 5000.0
// Methods
extension Int {
func repetitions(task: () -> Void) {
for _ in 0..<self {
task()
}
}
}
3.repetitions { print("Hello") }
// Mutating instance methods
extension Int {
mutating func square() {
self = self * self
}
}
var number = 3
number.square() // number is 9
// Subscripts
extension Int {
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
746381295[0] // 5
746381295[1] // 9
// Nested types
extension Int {
enum Kind {
case negative, zero, positive
}
var kind: Kind {
switch self {
case 0:
return .zero
case let x where x > 0:
return .positive
default:
return .negative
}
}
}
// Initializers
struct Size {
var width = 0.0, height = 0.0
}
struct Point4 {
var x = 0.0, y = 0.0
}
extension Rect {
init(center: Point4, size: Size) {
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
self.init(origin: Point4(x: originX, y: originY), size: size)
}
}// Generic functions
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temp = a
a = b
b = temp
}
var a = 5, b = 10
swapTwoValues(&a, &b)
// Generic types
struct Stack<Element> {
var items: [Element] = []
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element? {
return items.popLast()
}
}
var stack = Stack<Int>()
stack.push(1)
stack.push(2)
let top = stack.pop()
// Type constraints
func findIndex<T: Equatable>(of valueToFind: T, in array: [T]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
// Associated types
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
}
// Generic where clauses
func allItemsMatch<C1: Container, C2: Container>(
_ someContainer: C1, _ anotherContainer: C2
) -> Bool where C1.Item == C2.Item, C1.Item: Equatable {
if someContainer.count != anotherContainer.count {
return false
}
for i in 0..<someContainer.count {
if someContainer[i] != anotherContainer[i] {
return false
}
}
return true
}
// Extensions with generic where clause
extension Stack where Element: Equatable {
func isTop(_ item: Element) -> Bool {
guard let topItem = items.last else {
return false
}
return topItem == item
}
}
// Generic subscripts
extension Container {
subscript<Indices: Sequence>(indices: Indices) -> [Item]
where Indices.Iterator.Element == Int {
var result: [Item] = []
for index in indices {
result.append(self[index])
}
return result
}
}// Error types
enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeeded: Int)
case outOfStock
}
// Throwing functions
func canThrowError() throws -> String {
// This function may throw
return "Success"
}
func vend(itemName: String) throws {
guard itemName == "Chips" else {
throw VendingMachineError.invalidSelection
}
guard itemName.count > 0 else {
throw VendingMachineError.outOfStock
}
throw VendingMachineError.insufficientFunds(coinsNeeded: 5)
}
// Do-catch
do {
try vend(itemName: "Candy")
} catch VendingMachineError.invalidSelection {
print("Invalid selection")
} catch VendingMachineError.insufficientFunds(let coinsNeeded) {
print("Need \(coinsNeeded) more coins")
} catch {
print("Unexpected error: \(error)")
}
// Converting error to optional
let result = try? vend(itemName: "Chips") // Returns optional
if let value = result {
print(value)
}
// Disabling error propagation
let forcedResult = try! vend(itemName: "Chips") // Crashes if error
// Rethrowing functions
func execute(_ closure: () throws -> Void) rethrows {
try closure()
}
// Defer statement
func processFile() {
defer {
print("Closing file")
}
print("Opening file")
print("Processing file")
// File closes automatically
}
// Result type
enum NetworkError: Error {
case badURL
case noData
}
func fetchData(from url: String, completion: (Result<String, Error>) -> Void) {
// Implementation
completion(.success("Data"))
// or
completion(.failure(NetworkError.noData))
}
// Handling Result
fetchData(from: "https://example.com") { result in
switch result {
case .success(let data):
print("Got data: \(data)")
case .failure(let error):
print("Error: \(error)")
}
}// Async/Await (Swift 5.5+)
func fetchUser() async throws -> String {
// Simulate network call
try await Task.sleep(nanoseconds: 1_000_000_000)
return "User data"
}
// Calling async functions
Task {
do {
let user = try await fetchUser()
print(user)
} catch {
print("Error: \(error)")
}
}
// Async sequences
func fetchNumbers() -> AsyncStream<Int> {
AsyncStream { continuation in
for i in 1...5 {
continuation.yield(i)
}
continuation.finish()
}
}
Task {
for await number in fetchNumbers() {
print(number)
}
}
// Task groups
func fetchAllUsers() async throws -> [String] {
try await withThrowingTaskGroup(of: String.self) { group in
var users: [String] = []
for _ in 1...3 {
group.addTask {
try await fetchUser()
}
}
for try await user in group {
users.append(user)
}
return users
}
}
// Actors
actor Counter2 {
private var value = 0
func increment() {
value += 1
}
func getValue() -> Int {
return value
}
}
let counter2 = Counter2()
Task {
await counter2.increment()
let value = await counter2.getValue()
}
// Main actor
@MainActor
class ViewModel {
var data: String = ""
func updateData() async {
data = await fetchData()
}
func fetchData() async -> String {
return "Updated"
}
}
// Sendable protocol
struct UserData: Sendable {
let id: Int
let name: String
}
// Task cancellation
let task = Task {
try await longRunningOperation()
}
task.cancel() // Cancel the task
func longRunningOperation() async throws {
try Task.checkCancellation() // Check for cancellation
// Or
if Task.isCancelled {
return
}
}
// Structured concurrency
func parentTask() async {
async let child1 = fetchUser()
async let child2 = fetchUser()
let (result1, result2) = await (child1, child2)
print(result1, result2)
}// Automatic Reference Counting (ARC)
class Person3 {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
// Strong reference cycles
class Apartment {
let unit: String
var tenant: Person3? // Strong reference
init(unit: String) {
self.unit = unit
}
}
// Weak references (avoid retain cycles)
class Person4 {
let name: String
var apartment: Apartment2?
init(name: String) {
self.name = name
}
}
class Apartment2 {
let unit: String
weak var tenant: Person4? // Weak reference
init(unit: String) {
self.unit = unit
}
}
// Unowned references
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
}
class CreditCard {
let number: UInt64
unowned let customer: Customer // Unowned reference
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
}
// Closure capture lists
class SomeClass4 {
var closure: (() -> Void)?
var value = 10
func setupClosure() {
// Capture list to break retain cycle
closure = { [weak self] in
guard let self = self else { return }
print(self.value)
}
// Or with unowned
closure = { [unowned self] in
print(self.value)
}
}
}// Access levels
open class OpenClass { } // Accessible and subclassable everywhere
public class PublicClass { } // Accessible everywhere, subclassable only in module
internal class InternalClass { } // Default - accessible within module
fileprivate class FilePrivateClass { } // Accessible within file only
private class PrivateClass { } // Accessible within enclosing declaration
// Properties
class MyClass2 {
private var privateProperty = 0
fileprivate var filePrivateProperty = 0
internal var internalProperty = 0
public var publicProperty = 0
open var openProperty = 0
private(set) var readOnlyProperty = 0 // Read-only from outside
}
// Extensions and access control
extension MyClass2 {
// Can access private properties in same file
func modifyProperties() {
privateProperty = 10
filePrivateProperty = 20
}
}
// Subclassing restrictions
public class PublicBase {
open func openMethod() { }
public func publicMethod() { }
internal func internalMethod() { }
fileprivate func filePrivateMethod() { }
private func privateMethod() { }
}// Switch with patterns
let point5 = (2, 0)
switch point5 {
case (0, 0):
print("Origin")
case (_, 0):
print("On x-axis")
case (0, _):
print("On y-axis")
case (-2...2, -2...2):
print("Inside the box")
default:
print("Outside the box")
}
// Value bindings
switch point5 {
case (let x, 0):
print("On x-axis at \(x)")
case (0, let y):
print("On y-axis at \(y)")
case let (x, y):
print("At (\(x), \(y))")
}
// Where clause
switch point5 {
case let (x, y) where x == y:
print("On the line x == y")
case let (x, y) where x == -y:
print("On the line x == -y")
case (_, _):
print("Just some point")
}
// If case
let optionalValue: Int? = 5
if case let value? = optionalValue {
print("Has value: \(value)")
}
// For case
let array2: [Any] = [1, "Hello", 2, "World"]
for case let string as String in array2 {
print("String: \(string)")
}
// Enum pattern matching
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
let barcode = Barcode.qrCode("ABCDEFG")
switch barcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC: \(numberSystem)")
case .qrCode(let productCode):
print("QR: \(productCode)")
}
// Guard case
func extractValue(from optional: Int?) {
guard case let value? = optional else {
print("No value")
return
}
print(value)
}
// Expression pattern
let point6 = (1, 2)
switch point6 {
case (0...5, 0...5):
print("Inside")
default:
print("Outside")
}
// Custom pattern matching with ~=
struct Point7 {
var x: Int, y: Int
}
func ~= (pattern: String, value: Point7) -> Bool {
switch pattern {
case "origin":
return value.x == 0 && value.y == 0
case "positive":
return value.x > 0 && value.y > 0
default:
return false
}
}
let point7 = Point7(x: 5, y: 10)
if point7 ~= "positive" {
print("Positive point")
}// Checking type
class MediaItem {
var name: String
init(name: String) { self.name = name }
}
class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
class Song2: MediaItem {
var artist: String
init(name: String, artist: String) {
self.artist = artist
super.init(name: name)
}
}
// Type checking (is)
let mediaItem: MediaItem = Movie(name: "Inception", director: "Nolan")
if mediaItem is Movie {
print("It's a movie")
}
// Downcasting (as? and as!)
let items: [MediaItem] = [
Movie(name: "Inception", director: "Nolan"),
Song2(name: "Imagine", artist: "John Lennon")
]
for item in items {
if let movie = item as? Movie {
print("Movie: \(movie.name), director: \(movie.director)")
} else if let song = item as? Song2 {
print("Song: \(song.name), artist: \(song.artist)")
}
}
// Forced downcasting
let forcedMovie = items[0] as! Movie // Use only when certain
// Upcasting (as)
let upcastedItem: MediaItem = movie as MediaItem
// Any and AnyObject
var things: [Any] = []
things.append(42)
things.append("Hello")
things.append(Movie(name: "The Matrix", director: "Wachowski"))
for thing in things {
switch thing {
case let intValue as Int:
print("Integer: \(intValue)")
case let stringValue as String:
print("String: \(stringValue)")
case let movieValue as Movie:
print("Movie: \(movieValue.name)")
default:
print("Something else")
}
}// Property wrapper definition
@propertyWrapper
struct Clamped<Value: Comparable> {
private var value: Value
private let range: ClosedRange<Value>
init(wrappedValue: Value, _ range: ClosedRange<Value>) {
self.range = range
self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
}
var wrappedValue: Value {
get { return value }
set { value = min(max(newValue, range.lowerBound), range.upperBound) }
}
}
// Using property wrapper
struct Player {
@Clamped(0...100) var health: Int = 100
}
var player = Player()
player.health = 150 // Clamped to 100
player.health = -10 // Clamped to 0
// Projected value
@propertyWrapper
struct UserDefaultsStorage<T> {
let key: String
let defaultValue: T
var wrappedValue: T {
get { UserDefaults.standard.object(forKey: key) as? T ?? defaultValue }
set { UserDefaults.standard.set(newValue, forKey: key) }
}
var projectedValue: Self { return self }
}
struct Settings {
@UserDefaultsStorage(key: "username", defaultValue: "Guest")
var username: String
func reset() {
$username.store(defaultValue: "Guest")
}
}
// Property wrapper with additional parameters
@propertyWrapper
struct Formatted {
private var value: String
private var format: (String) -> String
init(wrappedValue: String, formatter: @escaping (String) -> String = { $0 }) {
self.value = formatter(wrappedValue)
self.format = formatter
}
var wrappedValue: String {
get { value }
set { value = format(newValue) }
}
}
struct User {
@Formatted { $0.capitalized }
var name: String
@Formatted { $0.trimmingCharacters(in: .whitespaces) }
var email: String
}// Result builder definition
@resultBuilder
struct HTMLBuilder {
static func buildBlock(_ components: String...) -> String {
return components.joined(separator: "\n")
}
static func buildOptional(_ component: String?) -> String {
return component ?? ""
}
static func buildEither(first component: String) -> String {
return component
}
static func buildEither(second component: String) -> String {
return component
}
static func buildArray(_ components: [String]) -> String {
return components.joined(separator: "\n")
}
}
// Using result builder
@HTMLBuilder
func buildPage(title: String, content: String) -> String {
"<html>"
"<head>"
"<title>\(title)</title>"
"</head>"
"<body>"
"<h1>\(title)</h1>"
"<p>\(content)</p>"
"</body>"
"</html>"
}
let page = buildPage(title: "Hello", content: "World")
// Conditional content
@HTMLBuilder
func buildConditional(showExtra: Bool) -> String {
"<div>Main content</div>"
if showExtra {
"<div>Extra content</div>"
}
}
// Loop support
@HTMLBuilder
func buildList(items: [String]) -> String {
"<ul>"
for item in items {
"<li>\(item)</li>"
}
"</ul>"
}
// SwiftUI example
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, World!")
.font(.title)
.padding()
HStack {
Button("Click me") {
print("Button clicked")
}
Spacer()
Text("SwiftUI")
}
}
}
}