Apple's modern language for iOS, macOS, watchOS, and tvOS apps. Fast, safe, and expressive.
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!
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")
}
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
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)!")
}
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
}
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()
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 }
}
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)
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
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)
}
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)
}
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")
}
}
}
}