COURSE ยท 12 LESSONS ยท 100% FREE
๐ŸŽ

Swift Programming

Apple's modern language for iOS, macOS, watchOS, and tvOS apps. Fast, safe, and expressive.

0Lessons
0Code Examples
ZeroPrerequisites
0%
You've completed 0 of 12 lessons
J/โ†“ Next
K/โ†‘ Prev
Esc Collapse
/ Search
Foundations
01

Hello World & Setup

print() for output. let for constants, var for variables. Swift Playground or Xcode.

let name = "Mayank"
let age = 15
print("Hello, \(name)! Age: \(age)")

// Types are inferred
let pi = 3.14         // Double
let count = 42        // Int
let passed = true     // Bool
let greeting: String = "Hi"

// Constants vs Variables
let fixed = 10        // can't change
var changing = 20
changing = 30         // OK
// fixed = 40          // Error!
02

Variables & Types

String, Int, Double, Bool, Array, Dictionary, Optional. Optionals are Swift's superpower.

let name: String = "Mayank"
let age: Int = 15
let pi: Double = 3.14159
let passed: Bool = true

// Arrays
let nums = [1, 2, 3, 4, 5]
var mutable = ["a", "b"]
mutable.append("c")

// Dictionaries
let person = ["name": "Mayank", "age": "15"]
print(person["name"] ?? "unknown")

// Optionals โ€” value might be missing
let maybe: String? = nil
let definite: String = maybe ?? "default"
print(definite)

// Unwrapping
if let safe = maybe {
    print(safe)
} else {
    print("nil")
}
03

Operators

Same math operators. Range operators (..< and ...). Ternary. Nil coalescing (??).

print(10 + 3)   // 13
print(10 - 3)   // 7
print(10 * 3)   // 30
print(10 / 3)   // 3
print(10 % 3)   // 1

// Range
for i in 0..<5 { print(i, terminator: " ") }
print()
for i in 1...5 { print(i, terminator: " ") }
print()

// Nil coalescing
let input: String? = nil
let value = input ?? "default"
print(value)

// Ternary
let score = 85
let grade = score >= 90 ? "A" : "B"
print(grade)

// String comparison
print("abc" < "abd")  // true
print("abc" == "abc")  // true
04

Control Flow

if/else, switch (exhaustive!), for-in, while, guard. Switch doesn't need break.

let score = 85
if score >= 90 { print("A") }
else if score >= 80 { print("B") }
else { print("C") }

// Switch (must be exhaustive)
let day = 3
switch day {
case 1: print("Monday")
case 2: print("Tuesday")
case 3: print("Wednesday")
default: print("Other")
}

// Pattern matching
let point = (3, 4)
switch point {
case (0, 0): print("origin")
case (_, 0): print("on x-axis")
case (0, _): print("on y-axis")
case let (x, y) where x == y: print("on diagonal")
default: print("somewhere else")
}

// Guard
func greet(_ name: String?) {
    guard let name = name else { print("Unknown"); return }
    print("Hello, \(name)!")
}
05

Functions & Closures

func keyword. Named params. Trailing closures. @discardableResult.

func add(_ a: Int, _ b: Int) -> Int { a + b }
func greet(name: String, prefix: String = "Hello") -> String {
    "\(prefix), \(name)!"
}

print(add(3, 4))
print(greet(name: "Mayank"))
print(greet(name: "World", prefix: "Hi"))

// Closures
let doubled = [1,2,3,4,5].map { $0 * 2 }
print(doubled)

let evens = [1,2,3,4,5].filter { $0 % 2 == 0 }
print(evens)

let sum = [1,2,3,4,5].reduce(0, +)
print(sum)

// Trailing closure
UIView.animate(withDuration: 0.3) {
    view.alpha = 1.0
}
OOP & Protocols
06

Classes & Structs

Reference types (class) vs value types (struct). Structs are preferred in Swift.

struct Point {
    var x: Double
    var y: Double
    func distance(to other: Point) -> Double {
        let dx = x - other.x
        let dy = y - other.y
        return (dx*dx + dy*dy).squareRoot()
    }
}

var p1 = Point(x: 0, y: 0)
var p2 = Point(x: 3, y: 4)
print(p1.distance(to: p2))  // 5.0

// Classes
class Dog {
    var name: String
    var age: Int
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    func bark() { print("\(name): Woof!") }
}

let d = Dog(name: "Rex", age: 5)
d.bark()
07

Protocols & Extensions

Protocols define contracts. Extensions add methods to existing types.

protocol Describable {
    var description: String { get }
    func describe()
}

extension Describable {
    func describe() { print(description) }
}

struct Person: Describable {
    let name: String
    let age: Int
    var description: String { "\(name), \(age)" }
}

let me = Person(name: "Mayank", age: 15)
me.describe()

// Extend existing types
extension String {
    var isPalindrome: Bool {
        let s = self.lowercased()
        return s == String(s.reversed())
    }
}

print("racecar".isPalindrome)  // true
print("hello".isPalindrome)    // false

// Protocol extensions
class Countable {
    var count = 0
    mutating func increment() { count += 1 }
}
08

Generics

Write code that works with any type. <T> placeholders. Same as C++/Java generics.

func swapValues<T>(_ a: inout T, _ b: inout T) {
    let temp = a; a = b; b = temp
}

var x = 10, y = 20
swapValues(&x, &y)
print(x, y)  // 20 10

struct Stack<Element> {
    private var items: [Element] = []
    mutating func push(_ item: Element) { items.append(item) }
    mutating func pop() -> Element? { items.popLast() }
    var isEmpty: Bool { items.isEmpty }
}

var stack = Stack<Int>()
stack.push(1)
stack.push(2)
stack.push(3)
while let item = stack.pop() { print(item, terminator: " ") }
print()

// Generic where clause
func findIndex<T: Equatable>(of value: T, in array: [T]) -> Int? {
    for (i, item) in array.enumerated() {
        if item == value { return i }
    }
    return nil
}
print(findIndex(of: "b", in: ["a","b","c"]) ?? -1)
09

Enums & Pattern Matching

Enums with associated values. switch with patterns. Optionals are enums!

enum Direction {
    case north, south, east, west
}

enum HTTPError {
    case notFound
    case serverError(Int)
    case custom(String, Int)
}

let error = HTTPError.serverError(500)
switch error {
case .notFound: print("404")
case .serverError(let code): print("Server error \(code)")
case .custom(let msg, let code): print("\(code): \(msg)")
}

// Optionals are enums!
enum Optional<T> {
    case some(T)
    case none
}

let maybe: Int? = .some(42)
if case .some(let value) = maybe {
    print(value)
}

// Enum with raw values
enum Planet: Int {
    case mercury = 1, venus, earth, mars
}
print(Planet(rawValue: 3)!)  // earth
Advanced
10

Error Handling

throw/try/catch. Error protocol. do-catch blocks. Result type for success/failure.

enum NetworkError: Error {
    case invalidURL
    case timeout
    case serverError(Int)
}

func fetchData(from url: String) throws -> String {
    guard !url.isEmpty else { throw NetworkError.invalidURL }
    guard url.hasPrefix("https") else { throw NetworkError.invalidURL }
    return "data from \(url)"
}

do {
    let data = try fetchData(from: "https://example.com")
    print(data)
} catch NetworkError.invalidURL {
    print("Invalid URL")
} catch NetworkError.serverError(let code) {
    print("Server error: \(code)")
} catch {
    print("Unknown error: \(error)")
}

// Result type
func divide(_ a: Int, by b: Int) -> Result<Int, Error> {
    guard b != 0 else { return .failure(NetworkError.custom("zero", 0)) }
    return .success(a / b)
}

switch divide(10, by: 3) {
case .success(let v): print(v)
case .failure(let e): print(e)
}
11

Async/Await

Swift 5.5+ structured concurrency. async functions, await, Task, actors for thread safety.

func fetchUser(id: Int) async throws -> String {
    try await Task.sleep(nanoseconds: 1_000_000_000)
    return "User \(id)"
}

// async let โ€” parallel
func loadDashboard() async throws {
    async let user = fetchUser(id: 1)
    async let posts = fetchUser(id: 2)
    let (u, p) = try await (user, posts)
    print(u, p)
}

// Actor โ€” thread-safe class
actor BankAccount {
    private var balance = 0
    func deposit(_ amount: Int) { balance += amount }
    func getBalance() -> Int { balance }
}

Task {
    let account = BankAccount()
    await account.deposit(100)
    let bal = await account.getBalance()
    print(bal)
}
12

SwiftUI Basics

Declarative UI. Views are structs. body returns some View. Modifiers chain.

import SwiftUI

struct ContentView: View {
    @State private var count = 0

    var body: some View {
        VStack(spacing: 20) {
            Text("Count: \(count)")
                .font(.largeTitle)
            Button("Increment") { count += 1 }
                .buttonStyle(.borderedProminent)
            List(1...10, id: \.self) { i in
                Text("Item \(i)")
            }
        }
        .padding()
    }
}

// Navigation
struct App: App {
    var body: some Scene {
        WindowGroup {
            NavigationView {
                List {
                    NavigationLink("Profile", destination: Text("Profile"))
                    NavigationLink("Settings", destination: Text("Settings"))
                }
                .navigationTitle("Menu")
            }
        }
    }
}