Swift is Apple’s modern programming language for iOS, iPadOS, macOS, watchOS, tvOS, and visionOS, and it also runs on Linux, Windows, and servers. Since its release in 2014, it has won developers over with clean syntax, strong safety guarantees, and great performance.
This guide walks through the language from the very first let to generics and opaque types. Go in order if you’re new; every section builds on the ones before it.
Article available Coming soon
1. Meet Swift
What is Swift Programming Language?
Swift is Apple’s modern, open-source programming language, introduced at Apple’s 2014 Worldwide Developers Conference (WWDC). Designed to be the successor to Objective-C,...
Advantages of Swift Over Objective-C
Objective-C, developed in the early 1980s, has long been the backbone of iOS and macOS development. Its deep integration with Apple’s ecosystem...
Swift Lexical Structure
The Swift lexical structure is composed of valid tokens, which serve as the fundamental building blocks that define the framework of any...
Swift Reserved Keywords, with brief explanations.
A reserved word is a term designated by the programming language that cannot be used as an identifier. This restriction is a...
Mastering Swift Style Guides: Elevate Your Code to the Next Level
Have you ever dived into an open-source project and marveled at the elegance and consistency of the codebase? 🧐 It’s no coincidence....
2. Variables and Data Types
Understanding Swift Variables and Constants: A Dive into Mutability
In every programming language, the ability to store and manage data is fundamental. In Swift, the distinction between variables and constants is...
Swift's Basic Data Types & Type Inference
Swift provides a rich array of built-in data types that are designed to accommodate various kinds of data, each serving a specific...
Why You Should Never Use Floating-Point or Double Data Types for Money Calculations!
Handling money in software is a task that requires precision, especially when dealing with fractions of currency like dollars and cents. One...
Understanding Swift: Differences Between Any, AnyObject, and AnyHashable
When working with Swift, one of the key decisions you’ll often face is how to represent data types. While specificity in defining...
Swift: The Difference Between Void and ()
Void is a concept familiar across many programming languages. In Swift, Void has a unique and specific meaning, rooted in the language’s...
Understanding Optionals in Swift: Handling Absence of Data Safely
In Swift, optionals play a crucial role in managing situations where a value might be absent. Unlike Objective-C, where nil can be...
Swift: The Difference Between nil, Nil, NULL, NSNull
As a programmer, you will often need to represent the concept of “nothingness.” In Swift and Objective-C, this idea manifests in various...
3. Operators and Strings
Operators You Actually Use
Swift’s operator set is broad, but a small set covers 95% of what you write daily. This guide focuses on the operators...
Mastering Swift Bitwise Operators: Theory and Practical Examples
Bitwise operators represent a formidable yet frequently underappreciated feature within the Swift programming language. Unlike logical operators such as && and ||,...
Strings and Characters That Don’t Bite
Swift strings are Unicode-correct, safe, and come with a few sharp edges if you assume they behave like simple arrays of bytes....
Using unicode markers (LTR: 0x200E, RTL:200F) to align "hybrid RTL/LTR strings" correctly.
When dealing with text that contains both Arabic and English languages, aligning it correctly can be quite challenging. This is especially true...
4. Collections and Control Flow
Arrays and Dictionaries in Swift
Almost every app is a story about lists and lookups: a feed of posts, a table of settings, a cache keyed by...
Swift Sets: Basics and Practical Examples
Swift offers three primary collection types: Arrays, Sets, and Dictionaries, each serving distinct purposes in data management. In this post, we will...
Control Flow in Swift: if, guard, switch, and Loops
Control flow decides which code runs and how many times. Swift’s toolbox looks familiar if you’ve used any C-style language, but almost...
Pattern Matching in Swift
Pattern matching is how Swift asks “does this value look like that?” and pulls the interesting parts out in the same breath....
5. Functions and Closures
Functions in Swift
Functions are the verbs of your code. Swift’s function syntax looks simple, but it’s carefully designed: argument labels make call sites read...
Closures in Swift
A closure is a block of code you can pass around and run later, together with the variables it uses from its...
Escaping and Non-Escaping Closures in Swift
Some closures run and are gone before the function that received them returns. Others are saved for later: stored in a property,...
Capture Lists in Swift Closures
A capture list is the small bracketed section at the start of a closure, like [weak self] or [count]. It controls how...
6. Building Your Own Types
Enumerations in Swift
In many languages, an enum is just a list of named integers. In Swift, enums are full types: they can carry data,...
Structures and Classes in Swift: Value vs. Reference Types
Structures and classes look almost identical in Swift: both have properties, methods, initializers, and extensions, and both can conform to protocols. The...
Properties in Swift
Properties attach values to types. Some store data, some compute it on demand, some react when they change, some wait until they’re...
Methods and mutating in Swift
Methods are functions that belong to a type. In classes they behave much like in any object-oriented language. Structs and enums add...
Subscripts in Swift
Every time you write array[0], dictionary["key"], or string[index], you’re calling a subscript. Subscripts are a shortcut for accessing parts of a value,...
Inheritance in Swift
Inheritance lets one class build on another: a subclass gets its superclass’s properties and methods, can add new ones, and can override...
Swift Root/Base Class & NSObject: A Quick Look
In the world of object-oriented programming (OOP), the concept of a root or base class is foundational for understanding class inheritance and...
7. Lifetime, Safety, and Errors
Initialization in Swift
Swift has one non-negotiable rule about initialization: every stored property must have a value before an instance can be used. There’s no...
Deinitialization in Swift
An initializer sets an object up; a deinitializer gets the last word before it disappears. In Swift, deinit runs automatically when an...
Automatic Reference Counting (ARC) in Swift
Swift manages the memory of class instances with Automatic Reference Counting (ARC). Every object keeps count of how many strong references point...
Zombies In Swift
In Swift, zombie objects is a debugging term for use-after-free bugs: your code tries to use an instance that has already been...
Memory Safety in Swift: Exclusive Access
Swift is designed so that, unless you explicitly opt out, your code can’t read uninitialized memory, run off the end of a...
Optional Chaining in Swift
Optional chaining lets you call properties, methods, and subscripts on a value that might be nil, in one expression. If any link...
Error Handling in Swift
Things go wrong: files are missing, networks drop, users type nonsense. Swift handles recoverable errors with throw, try, and catch, a model...
Access Control in Swift
Access control decides which parts of your code can see which other parts. It lets a type hide its implementation behind a...
8. Advanced Features
Protocols in Swift
A protocol describes what a type can do, without saying how. Classes, structs, and enums can all adopt protocols, which makes them...
Extensions in Swift
Extensions add new functionality to an existing type, even one you don’t own, like Int, String, or URL. They’re also how Swift...
Generics in Swift
Generics let you write code once and use it with many types, without giving up type safety. Array<Element>, Dictionary<Key, Value>, Optional<Wrapped>, and...
Phantom Types in Swift
Phantom types let you tuck extra meaning into Swift’s type system without changing anything at runtime. A phantom type is a generic...
Opaque and Boxed Types in Swift: some vs. any
some View is in every SwiftUI file, and any Error is in most error-handling code. Both keywords put a protocol where a...
Type Casting in Swift
Type casting answers two questions at runtime: “is this value of a certain type?” and “can I treat it as that type?”...
Nested Types in Swift
Some types only make sense in the context of another type. A playing card’s suit, a network client’s error, a view model’s...
Property Wrappers in Swift
If you’ve used SwiftUI, you’ve used property wrappers: @State, @Binding, @Environment, @AppStorage. A property wrapper packages up the logic for how a...
Macros in Swift
Swift macros, introduced in Swift 5.9, generate code at compile time. Write @Observable on a class, #Preview in a SwiftUI file, or...
Advanced and Custom Operators in Swift
Operators are just functions with special syntax. Beyond the everyday +, -, and ==, Swift has overflow operators, masking shifts, and a...
Swift Concurrency: async/await, Tasks, and Actors
For years, asynchronous Swift meant completion handlers, nested closures, and manual hops between dispatch queues, with data races found only by luck...
9. Under the Hood
These topics come up in day-to-day work, in debugging sessions, and very often in interviews:
Static vs. Dynamic Dispatch in Swift
When your code calls a method, the program has to decide which implementation runs. Sometimes the compiler knows at compile time: that’s...
Method Swizzling in Swift
Method swizzling swaps the implementation behind a method at runtime, so calling one method actually runs different code. It’s an Objective-C runtime...
Key-Value Observing (KVO) in Swift
Key-Value Observing lets one object be notified when a property of another object changes. It comes from Objective-C, and Apple’s frameworks still...
defer in Swift
defer schedules a block of code to run when the current scope exits, no matter how it exits: a normal return, an...
stride in Swift
Swift has no C-style for (int i = 0; i < 10; i += 2) loop. Ranges like 0..<10 cover steps of...
Reflection in Swift with Mirror
Reflection is a program inspecting its own structure at runtime: “what properties does this value have, and what’s in them?” Swift’s reflection...
Swift Interoperability with Objective-C, C, and C++
Swift didn’t arrive in an empty world. Apple’s platforms are built on decades of Objective-C and C, and huge amounts of valuable...
RunLoop Explained for Swift Developers
Why does a Timer stop firing while you scroll? Why does a timer created on a background thread never fire at all?...
Operation and OperationQueue in Swift
Before async/await, Apple platforms offered two main ways to run work concurrently: Grand Central Dispatch for lightweight blocks, and Operation with OperationQueue...
ABI Stability in Swift
In Swift’s early years, every app shipped its own copy of the Swift standard library, adding megabytes to every download, and a...
Swift Package Manager: A Practical Guide
Swift Package Manager (SwiftPM) is the official tool for building, sharing, and depending on Swift code. It’s part of the Swift toolchain...
Swift Evolution: How the Language Changes
Every Swift feature you use, from async/await to if expressions to macros, went through a public process before it shipped. That process...
Finding Memory Bugs with Address Sanitizer
Safe Swift code can’t corrupt memory. But the moment you use Unsafe pointers, call into C or C++, or depend on a...
Clean Code in Swift
Clean code is code that the next person, often you in six months, can read, trust, and change without fear. Most clean...
Up next
Object-Oriented Programming