Types, optionals, closures, protocols, structs vs classes, concurrency & SwiftUI basics
Language// Variables & constants
var name = "Alice" // mutable
let age = 30 // immutable (prefer let)
// Type annotations
let x: Int = 42
let pi: Double = 3.14
let flag: Bool = true
let ch: Character = "A"
// String interpolation
let msg = "Hello \(name), you are \(age)"
// Multi-line strings
let text = """
This is a
multi-line string
"""
// Type conversion
let intVal = Int("42") // Optional Int?
let dblVal = Double(age) // 30.0
let strVal = String(age) // "30"
// Tuples
let point = (x: 10, y: 20)
point.x // 10
let (a, b) = point // destructureSwift's optionals handle the absence of a value safely β no null pointer exceptions.
var email: String? = nil // optional String
email = "alice@example.com"
// Optional binding (safe unwrap)
if let e = email {
print("Email: \(e)")
}
// guard let (early exit)
guard let e = email else {
print("No email")
return
}
// e is available here
// Nil coalescing
let display = email ?? "No email"
// Optional chaining
let count = email?.count // Int? β nil if email is nil
// Force unwrap (avoid if possible)
let forced = email! // crashes if nil// Array
var nums: [Int] = [1, 2, 3]
nums.append(4)
nums.insert(0, at: 0)
nums.remove(at: 0)
nums.contains(3) // true
nums.sorted() // returns new sorted array
nums.filter { $0 > 2 } // [3, 4]
nums.map { $0 * 2 } // [2, 4, 6, 8]
nums.reduce(0, +) // 10
nums.compactMap { Int($0) } // filter nil from optionals
nums.flatMap { [$0, $0*2] }
// Dictionary
var scores: [String: Int] = ["Alice": 95, "Bob": 87]
scores["Alice"] // Optional Int?
scores["Charlie"] = 92 // add/update
scores.keys / scores.values
for (name, score) in scores { ... }
// Set
var tags: Set<String> = ["swift", "ios"]
tags.insert("macos")
tags.contains("swift")
tags.intersection(otherSet)
tags.union(otherSet)// if/else
if age >= 18 {
print("adult")
} else if age >= 13 {
print("teen")
} else {
print("child")
}
// switch (exhaustive, no fall-through)
switch role {
case "admin":
print("full access")
case "user", "member": // multiple values
print("limited")
case let r where r.hasPrefix("super"):
print("super role: \(r)")
default:
print("guest")
}
// for-in
for i in 0..<5 { } // 0,1,2,3,4
for i in 1...5 { } // 1,2,3,4,5
for (i, val) in arr.enumerated() { }
for _ in 0..<3 { } // ignore counter
// while
while x < 10 { x += 1 }
repeat { x += 1 } while x < 10 // do-while// Function with labels
func greet(person name: String, from city: String = "Unknown") -> String {
return "Hello \(name) from \(city)"
}
greet(person: "Alice", from: "NYC")
// Multiple return (tuple)
func minMax(_ arr: [Int]) -> (min: Int, max: Int) {
return (arr.min()!, arr.max()!)
}
// Closures
let add = { (a: Int, b: Int) -> Int in
return a + b
}
// Shorthand closure syntax
nums.sorted { $0 < $1 }
nums.sorted(by: <)
// Trailing closure
nums.filter { $0 > 3 }
.map { $0 * 2 }
.forEach { print($0) }
// @escaping (closure outlives function)
func fetch(completion: @escaping (String) -> Void) { }// Struct (value type β copied)
struct Point {
var x: Double
var y: Double
func distance(to other: Point) -> Double {
sqrt(pow(x - other.x, 2) + pow(y - other.y, 2))
}
mutating func translate(dx: Double, dy: Double) {
x += dx; y += dy
}
}
// Class (reference type β shared)
class Vehicle {
var speed: Double = 0
init(speed: Double) { self.speed = speed }
deinit { print("deallocated") }
}
class Car: Vehicle {
var brand: String
init(brand: String, speed: Double) {
self.brand = brand
super.init(speed: speed)
}
}
// Enum with associated values
enum Result<T> {
case success(T)
case failure(String)
}
enum Direction: String, CaseIterable {
case north, south, east, west
}// Protocol (like interface/trait)
protocol Drawable {
func draw()
var area: Double { get }
}
struct Circle: Drawable {
var radius: Double
var area: Double { .pi * radius * radius }
func draw() { print("Drawing circle r=\(radius)") }
}
// Extension (add functionality to existing types)
extension String {
var isEmail: Bool {
contains("@") && contains(".")
}
}
"a@b.com".isEmail // true
// Protocol extension (default implementation)
extension Drawable {
func description() -> String { "Area: \(area)" }
}enum AppError: Error {
case notFound
case unauthorized(String)
case serverError(code: Int)
}
func fetchUser(id: Int) throws -> User {
guard id > 0 else { throw AppError.notFound }
return User(name: "Alice")
}
// do-try-catch
do {
let user = try fetchUser(id: 1)
} catch AppError.notFound {
print("Not found")
} catch {
print("Error: \(error)")
}
// try? (returns optional), try! (force)
let user = try? fetchUser(id: 1) // User?// Async function
func fetchData(url: URL) async throws -> Data {
let (data, _) = try await URLSession.shared.data(from: url)
return data
}
// Call async function
Task {
let data = try await fetchData(url: myURL)
}
// Structured concurrency
async let users = fetchUsers()
async let posts = fetchPosts()
let (u, p) = try await (users, posts) // parallel
// Actor (thread-safe shared state)
actor Counter {
private var count = 0
func increment() { count += 1 }
func getCount() -> Int { count }
}import SwiftUI
struct ContentView: View {
@State private var count = 0
@State private var name = ""
var body: some View {
VStack(spacing: 20) {
Text("Count: \(count)")
.font(.title)
.foregroundColor(.blue)
Button("Increment") { count += 1 }
.buttonStyle(.borderedProminent)
TextField("Enter name", text: $name)
.textFieldStyle(.roundedBorder)
List {
ForEach(items) { item in
Text(item.name)
}
}
}
.padding()
.onAppear { loadData() }
}
}
// Property wrappers
// @State β local mutable state
// @Binding β two-way binding to parent
// @ObservedObject β external observable
// @EnvironmentObject β shared app state
// @Published β auto-notify on change