Swift Cheatsheet

1. Variables and Constants

let age: Int = 30  // Constant
var name: String = "John"  // Variable
var isStudent = true  // Type inference

// Arrays
let numbers: [Int] = [1, 2, 3]
let emptyArray = [String]()  // Empty array

// Dictionaries
let person: [String: Any] = ["name": "John", "age": 30]

// Tuples
let coordinates: (Int, Int) = (10, 20)
let (x, y) = coordinates
print(x, y)  // Output: 10, 20

2. Control Flow (Conditionals, Switches, Loops)

// If-else
if age > 18 {
  print("Adult")
} else {
  print("Minor")
}

// Switch statement
let day = 2
switch day {
  case 1:
    print("Monday")
  case 2:
    print("Tuesday")
  default:
    print("Other day")
}

// For-in loop
for i in 1...5 {
  print(i)
}

// While loop
var counter = 0
while counter < 5 {
  print(counter)
  counter += 1
}

3. Functions and Closures

// Simple function
func greet(name: String) -> String {
  return "Hello, \(name)"
}

let message = greet(name: "John")
print(message)

// Closures
let add: (Int, Int) -> Int = { (a, b) in return a + b }
print(add(5, 3))  // Output: 8

// Trailing closure
let numbers = [1, 2, 3]
numbers.forEach { num in
  print(num)
}

4. Optionals and Unwrapping

// Optional
var middleName: String? = nil

// Force unwrapping (not recommended)
if middleName != nil {
  print(middleName!)
}

// Optional binding
if let mName = middleName {
  print(mName)
} else {
  print("No middle name")
}

// Nil coalescing
let fullName = middleName ?? "No middle name"
print(fullName)

5. Classes, Structures, and Enums

// Class
class Animal {
  var name: String
  init(name: String) {
    self.name = name
  }
  func speak() {
    print("\(name) makes a sound.")
  }
}

class Dog: Animal {
  override func speak() {
    print("\(name) barks.")
  }
}

let rex = Dog(name: "Rex")
rex.speak()

// Struct
struct Point {
  var x: Int
  var y: Int
}
let p = Point(x: 10, y: 20)
print(p.x, p.y)  // Output: 10, 20

// Enum
enum Direction {
  case north, south, east, west
}
let heading = Direction.north
switch heading {
  case .north:
    print("Heading north")
  default:
    print("Going somewhere else")
}

6. Protocols and Extensions

// Protocol (similar to interface)
protocol Describable {
  func describe() -> String
}

class Car: Describable {
  func describe() -> String {
    return "A car"
  }
}
let car = Car()
print(car.describe())  // Output: A car

// Extensions
extension Int {
  func squared() -> Int {
    return self * self
  }
}
let num = 5
print(num.squared())  // Output: 25

7. Generics

// Generic function
func swapValues<T>(_ a: inout T, _ b: inout T) {
  let temp = a
  a = b
  b = temp
}
var x = 5
var y = 10
swapValues(&x, &y)
print("x: \(x), y: \(y)")  // Output: x: 10, y: 5

// Generic class
class Box<T> {
  var value: T
  init(value: T) {
    self.value = value
  }
}
let intBox = Box(value: 5)
print(intBox.value)

8. Error Handling

// Error enum
enum DivisionError: Error {
  case divideByZero
}

func divide(_ a: Int, _ b: Int) throws -> Int {
  if b == 0 {
    throw DivisionError.divideByZero
  }
  return a / b
}

// Handling errors
do {
  let result = try divide(10, 0)
  print(result)
} catch DivisionError.divideByZero {
  print("Cannot divide by zero")
}

9. Memory Management and ARC

// Automatic Reference Counting (ARC)
class Person {
  let name: String
  init(name: String) {
    self.name = name
  }
  deinit {
    print("\(name) is being deinitialized")
  }
}

var person1: Person? = Person(name: "John")
person1 = nil  // Deinitialized automatically

10. Concurrency (GCD and async/await)

// GCD for background tasks
dispatchQueue.global().async {
  print("Background work")
  DispatchQueue.main.async {
    print("Back on the main thread")
  }
}

// Async/await
func fetchData() async -> String {
  return "Data loaded"
}
Task {
  let result = await fetchData()
  print(result)
}

11. SwiftUI

import SwiftUI

struct ContentView: View {
  @State private var name = ""

  var body: some View {
    VStack {
      TextField("Enter your name", text: $name)
        .padding()
      Text("Hello, \(name)")
        .padding()
    }
  }
}

@main
struct MyApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}

12. Functional Programming in Swift

// Map, Filter, Reduce
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map { $0 * 2 }
print(doubled)  // Output: [2, 4, 6, 8, 10]

let evenNumbers = numbers.filter { $0 % 2 == 0 }
print(evenNumbers)  // Output: [2, 4]

let sum = numbers.reduce(0, +)
print(sum)  // Output: 15

13. KeyPaths

// KeyPaths allow referencing properties indirectly
struct Person {
  var name: String
  var age: Int
}
let john = Person(name: "John", age: 30)

let nameKeyPath = \Person.name
print(john[keyPath: nameKeyPath])  // Output: John

14. Property Wrappers

// Property wrappers
@propertyWrapper
struct Capitalized {
  private var text: String = ""
  var wrappedValue: String {
    get { text.uppercased() }
    set { text = newValue }
  }
}

struct User {
  @Capitalized var username: String
}

var user = User(username: "john_doe")
print(user.username)  // Output: JOHN_DOE

15. Closures and Capture Lists

// Capturing values
func makeCounter() -> () -> Int {
  var count = 0
  return { count += 1; return count }
}

let counter = makeCounter()
print(counter())  // Output: 1
print(counter())  // Output: 2

// Capture list
let closure: () -> Void = { [count = 10] in
  print(count)
}
closure()  // Output: 10

16. Type Casting (as, as?, as!)

// Type casting using 'as', 'as?', and 'as!'
class Animal {}
class Dog: Animal {}

let animal: Animal = Dog()

// Optional downcasting (as?)
if let dog = animal as? Dog {
  print("This is a dog.")
}

// Forced downcasting (as!)
let dog = animal as! Dog
print("Forced cast to dog")

17. Error Propagation and Throwing Initializers

// Error propagation
func readFile(named: String) throws -> String {
  if named == "" {
    throw NSError(domain: "", code: 0, userInfo: nil)
  }
  return "File content"
}

// Throwing initializer
class Document {
  let content: String
  init(filename: String) throws {
    self.content = try readFile(named: filename)
  }
}