Introduction
Swift is Apple’s modern programming language for iOS, iPadOS, macOS, watchOS and tvOS. It’s safe by default (thanks to Optionals and type inference), fast, and expressive—great for beginners, powerful for pros.
Setup: Xcode & tools
- Install the latest Xcode from the Mac App Store.
- Open Xcode → Preferences → Locations → set the Command Line Tools.
- Optional: install Homebrew for helpful dev tools.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew --version
Swift Playgrounds
Playgrounds give instant feedback. In Xcode: File → New → Playground. Type code and see results immediately.
import Foundation
print("Hello, Swift 👋")
Language basics
let appName: String = "Ondevtra" // constant
var version = 1 // type inferred as Int
var price: Double = 3.99
for i in 1...3 { print(i) }
let score = 82
switch score {
case 0..50: print("Needs work")
case 50..90: print("Good")
default: print("Great!")
}
Optionals & safety
Optionals represent “a value or no value”. You must unwrap before use—this prevents many runtime crashes.
var nickname: String? = nil
nickname = "Sim"
// Safe unwrapping
if let name = nickname { print("Hi, \(name)") }
Functions & closures
func greet(_ who: String) -> String {
return "Hello, \(who)!"
}
greet("world")
let names = ["Ava", "Ben", "Cara"]
let sorted = names.sorted { a, b in a < b }
Structs, classes & enums
- Structs are value types (copied on assignment), great for models.
- Classes are reference types (shared identity), used with inheritance.
- Enums represent a fixed set of cases; can have associated values.
struct User { let id: Int; var name: String }
enum Mood { case happy, sad, neutral }
class Session { var isLoggedIn = false }
Protocols & extensions
Protocols define capabilities; any type can conform. Extensions add behavior to existing types—clean and reusable.
protocol Printable { func pretty() -> String }
extension User: Printable {
func pretty() -> String { return "#\(id) \(name)" }
}
Error handling
enum FetchError: Error { case offline, badData }
func fetch() throws -> String {
throw FetchError.offline
}
do {
let _ = try fetch()
} catch {
print(error)
}
Concurrency (async/await)
Swift’s structured concurrency makes background work readable and safe.
func download() async throws -> Data {
let url = URL(string: "https://example.com/data.json")!
let (data, _) = try await URLSession.shared.data(from: url)
return data
}
Task {
if let data = try? await download() { print(data.count) }
}
SwiftUI in 20 minutes
SwiftUI is a declarative UI toolkit. You describe the view; the framework handles updates.
import SwiftUI
struct HelloView: View {
@State private var count = 0
var body: some View {
VStack(spacing: 12) {
Text("Hello, SwiftUI").font(.title)
Button("Tap: \(count)") { count += 1 }
}.padding()
}
}
Your first app: step-by-step
- Xcode → File → New → App → iOS App with Swift + SwiftUI.
- Replace the template ContentView with your custom view.
- Run on the Simulator (choose a device at the top of Xcode).
struct ContentView: View {
@State private var name = ""
var body: some View {
NavigationStack {
Form {
TextField("Your name", text: $name)
Text("Welcome, \(name.isEmpty ? "friend" : name)!")
}
.navigationTitle("Starter App")
}
}
}
Networking & JSON
Decode JSON using Codable
.
struct Post: Codable, Identifiable { let id: Int; let title: String }
class PostVM: ObservableObject {
@Published var posts: [Post] = []
func load() async {
guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else { return }
do {
let (data, _) = try await URLSession.shared.data(from: url)
let list = try JSONDecoder().decode([Post].self, from: data)
await MainActor.run { self.posts = list.prefix(5).map{$0} }
} catch { print(error) }
}
}
struct PostListView: View {
@StateObject private var vm = PostVM()
var body: some View {
List(vm.posts) { Text($0.title) }
.task { await vm.load() }
.navigationTitle("Posts")
}
}
Unit tests
Add a Test target and write focused tests.
import XCTest
@testable import StarterApp
final class StarterAppTests: XCTestCase {
func testGreeting() {
let text = greet("Ada")
XCTAssertTrue(text.contains("Ada"))
}
}
Best practices
- Prefer structs for models; keep classes for shared identity or Obj-C interop.
- Use Optionals thoughtfully; avoid force-unwraps (
!
) unless guaranteed safe. - Leverage protocols & extensions for reusable behavior.
- Keep your UI stateless and derive views from data.
- Adopt async/await for clarity in concurrent code.
Resources
- Apple’s free book: The Swift Programming Language.
- Swift Forums & Swift.org documentation.
- Hacking with Swift (project-based tutorials).
Glossary
- Optional: a variable that may hold a value or
nil
. - Codable: protocols to encode/decode data.
- ObservableObject/@State: SwiftUI data flow primitives.
FAQ
Do I need a paid Apple Developer account? No for learning. You only need it to publish to the App Store.
Mac required? Yes for Xcode and iOS simulators.
How long until I build something? In a weekend, you can ship a simple SwiftUI app.
You might also like