<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Divyesh Vekariya on Medium]]></title>
        <description><![CDATA[Stories by Divyesh Vekariya on Medium]]></description>
        <link>https://medium.com/@dkvekariya?source=rss-6317b0b805bf------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*Zpy6MH_OYXnmPOzRQZUifQ.png</url>
            <title>Stories by Divyesh Vekariya on Medium</title>
            <link>https://medium.com/@dkvekariya?source=rss-6317b0b805bf------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 18 Oct 2026 05:48:55 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@dkvekariya/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Functional Programming in Swift: map, filter, reduce, and Beyond]]></title>
            <link>https://dkvekariya.medium.com/functional-programming-in-swift-map-filter-reduce-and-beyond-a3ad4bb2ce26?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/a3ad4bb2ce26</guid>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios-development]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 16 Oct 2026 14:16:01 GMT</pubDate>
            <atom:updated>2026-10-16T14:16:01.824Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Stop writing loops to transform data. Start writing transformations that compose.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pYji0shlbToCuffDNDPJgA.png" /></figure><h3>A Different Way to Think About Data</h3><p>Most developers learn to transform data with loops. Iterate, check a condition, append to a result array, return it. It works. It is also verbose, stateful, and harder to test than it needs to be.</p><p>Functional programming offers a different mental model. Instead of describing <em>how</em> to transform data step by step, you describe <em>what</em> the transformation is. The result is code that is shorter, more readable, and easier to combine into pipelines.</p><p>Swift has first-class support for this style. You have been using the pieces since <a href="https://dkvekariya.medium.com/91d441e21f24"><strong>Article 7 (closures</strong></a>). Now they come together.</p><h3>map: Transform Every Element</h3><p>map applies a transformation to every element and returns a new collection.</p><pre>let prices = [10.0, 25.0, 8.5, 42.0]<br><br>// Loop style<br>var discounted: [Double] = []<br>for price in prices {<br>    discounted.append(price * 0.9)<br>}<br><br>// Functional style<br>let discounted = prices.map { $0 * 0.9 }<br>// [9.0, 22.5, 7.65, 37.8]</pre><p>Same result. The functional version says exactly what it is: a 10% discount applied to every price. No accumulator variable, no loop management, no mutation.</p><pre>let usernames = [&quot;aryan&quot;, &quot;riya&quot;, &quot;dev&quot;]<br>let displayNames = usernames.map { $0.capitalized }<br>// [&quot;Aryan&quot;, &quot;Riya&quot;, &quot;Dev&quot;]<br><br>struct User { let id: Int; let name: String }<br>let users = [User(id: 1, name: &quot;Aryan&quot;), User(id: 2, name: &quot;Riya&quot;)]<br>let names = users.map { $0.name }<br>// [&quot;Aryan&quot;, &quot;Riya&quot;]</pre><p>map works on any Sequence and always returns an array of the same length.</p><h3>filter: Keep What Passes</h3><p>filter returns only the elements that satisfy a condition.</p><pre>let scores = [45, 78, 92, 61, 88, 34, 95]<br><br>let passing = scores.filter { $0 &gt;= 60 }<br>// [78, 92, 61, 88, 95]<br>let products = [<br>    Product(name: &quot;Swift Book&quot;, inStock: true),<br>    Product(name: &quot;Keyboard&quot;, inStock: false),<br>    Product(name: &quot;Monitor&quot;, inStock: true)<br>]<br>let available = products.filter { $0.inStock }<br>// [Swift Book, Monitor]</pre><p>The closure returns Bool. Elements that return true are kept. Elements that return false are dropped.</p><h3>reduce: Collapse to a Single Value</h3><p>reduce takes a collection and produces a single result by combining elements one at a time.</p><pre>let numbers = [1, 2, 3, 4, 5]<br>let sum = numbers.reduce(0) { result, next in result + next }<br><br>// 15<br>// Shorthand with operator function<br>let sum = numbers.reduce(0, +)<br><br>// 15<br>let words = [&quot;Swift&quot;, &quot;is&quot;, &quot;great&quot;]<br>let sentence = words.reduce(&quot;&quot;) { $0 + ($0.isEmpty ? &quot;&quot; : &quot; &quot;) + $1 }<br>// &quot;Swift is great&quot;</pre><p>The first argument is the initial value. The closure takes the accumulated result and the next element, and returns the new accumulated value.</p><pre>// Real-world: total cart price with discount<br>struct CartItem { let price: Double; let quantity: Int }<br><br>let cart = [CartItem(price: 9.99, quantity: 2), CartItem(price: 24.99, quantity: 1)]<br>let total = cart.reduce(0.0) { $0 + ($1.price * Double($1.quantity)) }<br>// 44.97</pre><h3>Chaining: Build Pipelines</h3><p>The real power comes from chaining transformations.</p><pre>let orders = [<br>    Order(amount: 120.0, isPaid: true),<br>    Order(amount: 45.0, isPaid: false),<br>    Order(amount: 300.0, isPaid: true),<br>    Order(amount: 15.0, isPaid: false),<br>    Order(amount: 89.0, isPaid: true)<br>]<br><br>let totalPaidRevenue = orders<br>    .filter { $0.isPaid }         // keep paid orders<br>    .map { $0.amount }            // extract amounts<br>    .reduce(0, +)                 // sum them<br>// 509.0</pre><p>Each step is a single, focused transformation. Read it top to bottom like a sentence. No intermediate variables, no mutation, no mental overhead tracking state.</p><h3>flatMap: Transform and Flatten</h3><p>flatMap is map followed by flattening one level of nesting.</p><pre>let sentences = [&quot;Swift is great&quot;, &quot;Generics are powerful&quot;]<br><br>let words = sentences.map { $0.split(separator: &quot; &quot;).map(String.init) }<br>// [[&quot;Swift&quot;, &quot;is&quot;, &quot;great&quot;], [&quot;Generics&quot;, &quot;are&quot;, &quot;powerful&quot;]]<br>// Nested array - probably not what you want<br>let words = sentences.flatMap { $0.split(separator: &quot; &quot;).map(String.init) }<br>// [&quot;Swift&quot;, &quot;is&quot;, &quot;great&quot;, &quot;Generics&quot;, &quot;are&quot;, &quot;powerful&quot;]<br>// Flat array - much more useful<br><br>// Flattening optional results<br>let strings = [&quot;1&quot;, &quot;two&quot;, &quot;3&quot;, &quot;four&quot;, &quot;5&quot;]<br>let numbers = strings.flatMap { Int($0) }<br>// [1, 3, 5] - nils removed, results flattened</pre><p>When the transformation returns an array, flatMap merges all the resulting arrays into one.</p><h3>compactMap: Remove Nils</h3><p>compactMap maps and removes nil results in one step.</p><pre>let inputs = [&quot;42&quot;, &quot;hello&quot;, &quot;7&quot;, &quot;world&quot;, &quot;13&quot;]<br>let numbers = inputs.compactMap { Int($0) }<br>// [42, 7, 13]<br><br>let rawIDs: [String?] = [&quot;usr_1&quot;, nil, &quot;usr_3&quot;, nil, &quot;usr_5&quot;]<br>let validIDs = rawIDs.compactMap { $0 }<br>// [&quot;usr_1&quot;, &quot;usr_3&quot;, &quot;usr_5&quot;]</pre><p>This replaces a common pattern:</p><pre>// Before<br>var result: [Int] = []<br>for str in inputs {<br>    if let n = Int(str) { result.append(n) }<br>}<br><br>// After<br>let result = inputs.compactMap { Int($0) }</pre><p>Same output. Dramatically less code. No mutation.</p><h3>zip: Combine Two Sequences</h3><p>zip pairs elements from two sequences together.</p><pre>let names = [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Charlie&quot;]<br>let scores = [95, 87, 92]<br><br>let leaderboard = zip(names, scores).map { &quot;\($0): \($1)&quot; }<br>// [&quot;Alice: 95&quot;, &quot;Bob: 87&quot;, &quot;Charlie: 92&quot;]<br>// Sort by score descending<br>let ranked = zip(names, scores)<br>    .sorted { $0.1 &gt; $1.1 }<br>    .map { &quot;\($0.0): \($0.1)&quot; }<br>// [&quot;Alice: 95&quot;, &quot;Charlie: 92&quot;, &quot;Bob: 87&quot;]</pre><p>zip stops at the shorter sequence, so no index out of bounds risk.</p><h3>sorted and Custom Comparators</h3><pre>let users = [<br>    User(name: &quot;Riya&quot;, age: 25),<br>    User(name: &quot;Aryan&quot;, age: 28),<br>    User(name: &quot;Dev&quot;, age: 22)<br>]<br><br>// Sort by age ascending<br>let byAge = users.sorted { $0.age &lt; $1.age }<br><br>// Sort by name<br>let byName = users.sorted { $0.name &lt; $1.name }<br><br>// Sort by multiple criteria: age descending, then name ascending<br>let complex = users.sorted {<br>    if $0.age != $1.age { return $0.age &gt; $1.age }<br>    return $0.name &lt; $1.name<br>}</pre><h3>Real-World Pipeline: Processing an API Response</h3><pre>struct APIProduct: Decodable {<br>    let id: String<br>    let name: String<br>    let price: Double?<br>    let category: String<br>    let isAvailable: Bool<br>}<br><br>struct DisplayProduct {<br>    let id: String<br>    let title: String<br>    let formattedPrice: String<br>}<br>func processProducts(_ raw: [APIProduct]) -&gt; [DisplayProduct] {<br>    raw<br>        .filter { $0.isAvailable &amp;&amp; $0.price != nil }<br>        .filter { $0.category == &quot;electronics&quot; }<br>        .sorted { $0.price! &lt; $1.price! }<br>        .prefix(10)<br>        .compactMap { product -&gt; DisplayProduct? in<br>            guard let price = product.price else { return nil }<br>            return DisplayProduct(<br>                id: product.id,<br>                title: product.name.capitalized,<br>                formattedPrice: String(format: &quot;$%.2f&quot;, price)<br>            )<br>        }<br>}</pre><p>No mutation. No intermediate arrays. One clean pipeline from raw API data to display-ready models.</p><h3>Interview Questions</h3><p><strong>Q: What is the difference between map, flatMap, and compactMap in Swift?</strong></p><p>map transforms each element and returns an array of the same length. flatMap transforms each element where the transformation returns a sequence, then flattens all results into a single array. compactMap transforms each element, removes nil results, and returns an array of unwrapped values. Use map for one-to-one transformations, flatMap when each element produces multiple results, and compactMap when the transformation might fail and you want to silently drop failures.</p><p><strong>Q: Why is the functional style preferred over loops for data transformation in Swift?</strong></p><p>Functional transformations are declarative. They say what the result is rather than how to produce it step by step. This makes each step independently readable and testable. Chained transformations have no shared mutable state between steps, which eliminates a whole class of bugs. They also compose cleanly: adding a new filter or transform means adding one line to the chain rather than modifying existing loop logic.</p><h3>Summary</h3><ul><li>map transforms every element and returns an array of the same length.</li><li>filter returns only elements that satisfy a condition.</li><li>reduce collapses a collection to a single value.</li><li>Chaining filter, map, and reduce creates readable, declarative data pipelines.</li><li>flatMap maps and flattens one level of nesting in the result.</li><li>compactMap maps and removes nil results in a single step.</li><li>zip pairs elements from two sequences without risk of index out of bounds.</li><li>sorted accepts a comparator closure and supports multi-criteria sorting.</li><li>Functional transformations have no shared mutable state, making them easier to test and compose.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Given let temperatures = [36.6, 37.2, 38.1, 36.9, 39.0, 37.5], use filter to find fever temperatures (above 37.5), map to format them as strings like &quot;38.1°C&quot;, and reduce to find the average fever temperature.</li><li><strong>Intermediate:</strong> You have let logs: [String] = [&quot;ERROR: disk full&quot;, &quot;INFO: app started&quot;, &quot;ERROR: timeout&quot;, &quot;DEBUG: request sent&quot;, &quot;ERROR: auth failed&quot;]. Use compactMap to extract only the error messages (remove the &quot;ERROR: &quot; prefix), sorted to alphabetize them, and produce a single summary string using reduce.</li><li><strong>Advanced:</strong> Build a Pipeline&lt;Input, Output&gt; struct that wraps a transformation function. Add a then&lt;NewOutput&gt; method that chains another Pipeline, returning a new Pipeline&lt;Input, NewOutput&gt;. Use it to build a reusable product-processing pipeline that filters, sorts, and maps API products in a composable way. Show how individual pipeline steps can be unit tested in isolation.</li></ol><h3>What’s Next</h3><p><strong>Article 18: Swift Async/Await: Modern Concurrency Without the Callback Chaos</strong></p><p>Functional programming gives you cleaner synchronous data transformations. Async/await gives you cleaner asynchronous ones. Before async/await, every network call, file read, and background task meant nested completion handlers and manual thread management. Swift 5.5 changed that entirely. It is one of the most impactful additions to the language in years.</p><p><em>Part of </em><strong><em>Swift from Zero to Senior</em></strong><em> — a complete iOS engineering curriculum on Medium.</em></p><p><strong>If data pipelines just replaced a pile of loops in your head, tap 👏 up to 50 times and do 🔁. It helps this series reach developers still writing nested for-loops to transform API responses.</strong></p><p><strong>Follow me</strong> so Article 18 lands in your feed automatically. Async/await is next and it will change how you write every network call going forward.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a3ad4bb2ce26" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift Generics: Write Once, Work With Any Type]]></title>
            <link>https://dkvekariya.medium.com/swift-generics-write-once-work-with-any-type-d6640afccdc9?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/d6640afccdc9</guid>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 09 Oct 2026 14:16:01 GMT</pubDate>
            <atom:updated>2026-10-09T14:16:01.722Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>The feature behind Optional, Result, Array, and every reusable component you will ever build.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gol7L4VAPgEMDbIsU-6kug.png" /></figure><h3>Why Generics Exist</h3><p>Without generics, you write the same logic multiple times for different types.</p><pre>func printInt(_ value: Int) { print(value) }<br>func printString(_ value: String) { print(value) }<br>func printDouble(_ value: Double) { print(value) }</pre><p>Three functions. Same body. Only the type differs. This does not scale. Generics solve it.</p><pre>func printValue&lt;T&gt;(_ value: T) {<br>    print(value)<br>}<br><br>printValue(42)        // works<br>printValue(&quot;hello&quot;)   // works<br>printValue(3.14)      // works</pre><p>One function. Any type. The compiler generates the right version for each call automatically.</p><h3>Generic Functions</h3><p>The &lt;T&gt; is a <strong>type parameter</strong>. It is a placeholder that Swift fills in at the call site.</p><pre>func swap&lt;T&gt;(_ a: inout T, _ b: inout T) {<br>    let temp = a<br>    a = b<br>    b = temp<br>}<br><br>var x = 10<br>var y = 20<br>swap(&amp;x, &amp;y)<br><br>print(x, y)  // 20 10<br><br>var hello = &quot;hello&quot;<br>var world = &quot;world&quot;<br>swap(&amp;hello, &amp;world)<br><br>print(hello, world)  // world hello</pre><p>T can be named anything. T and U are conventions for single and paired type parameters. Use descriptive names when the meaning matters: Element, Key, Value.</p><h3>Generic Types</h3><p><a href="https://dkvekariya.medium.com/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659"><strong>Structs</strong></a>, classes, and <a href="https://dkvekariya.medium.com/swift-enums-associated-values-raw-values-and-pattern-matching-a5844461beb1"><strong>enums</strong></a> can all be generic.</p><pre>struct Stack&lt;Element&gt; {<br>    private var storage: [Element] = []<br><br>    mutating func push(_ item: Element) {<br>        storage.append(item)<br>    }<br><br>    mutating func pop() -&gt; Element? {<br>        storage.popLast()<br>    }<br><br>    var top: Element? {<br>        storage.last<br>    }<br><br>    var isEmpty: Bool {<br>        storage.isEmpty<br>    }<br>}<br><br>var intStack = Stack&lt;Int&gt;()<br>intStack.push(1)<br>intStack.push(2)<br>intStack.push(3)<br><br>print(intStack.pop())  // Optional(3)<br><br>var stringStack = Stack&lt;String&gt;()<br>stringStack.push(&quot;Swift&quot;)<br>stringStack.push(&quot;Generics&quot;)<br><br>print(stringStack.top)  // Optional(&quot;Generics&quot;)</pre><p>One Stack implementation. Works for Int, String, User, or any type you throw at it. The type safety is fully preserved — an Stack&lt;Int&gt; cannot hold a String.</p><h3>Type Constraints</h3><p>Unconstrained generics can only use operations available on every type. To use specific capabilities, add a constraint.</p><pre>// Without constraint — T could be anything, very limited<br>func bigger&lt;T&gt;(_ a: T, _ b: T) -&gt; T {<br>    // Cannot use &gt; here — not all types support it<br>}<br><br>// With Comparable constraint - now &gt; is available<br>func bigger&lt;T: Comparable&gt;(_ a: T, _ b: T) -&gt; T {<br>    a &gt; b ? a : b<br>}<br><br>bigger(3, 7)        // 7<br>bigger(&quot;apple&quot;, &quot;mango&quot;)  // &quot;mango&quot; - String is Comparable</pre><p>Constraints can stack:</p><pre>func findAndPrint&lt;T: Comparable &amp; CustomStringConvertible&gt;(_ array: [T]) {<br>    if let max = array.max() {<br>        print(&quot;Max: \(max.description)&quot;)<br>    }<br>}</pre><p>T must be both Comparable and CustomStringConvertible. The compiler enforces this at every call site.</p><h3>Generic Constraints with where</h3><p>The where clause adds constraints inline without cluttering the function signature.</p><pre>func merge&lt;T, U&gt;(_ dict1: [T: U], _ dict2: [T: U]) -&gt; [T: U] where T: Hashable {<br>    dict1.merging(dict2) { first, _ in first }<br>}<br><br>func allEqual&lt;T: Collection&gt;(_ collection: T) -&gt; Bool where T.Element: Equatable {<br>    guard let first = collection.first else { return true }<br>    return collection.allSatisfy { $0 == first }<br>}<br><br>allEqual([1, 1, 1])       // true<br>allEqual([&quot;a&quot;, &quot;a&quot;, &quot;b&quot;]) // false</pre><p>where is particularly useful when constraining associated types of <a href="https://dkvekariya.medium.com/swift-protocols-contracts-conformance-and-protocol-oriented-programming-6b9d48617970"><strong>protocols</strong></a> used as parameters.</p><h3>Associated Types in Protocols</h3><p><a href="https://dkvekariya.medium.com/swift-protocols-contracts-conformance-and-protocol-oriented-programming-6b9d48617970"><strong>Protocols</strong></a> use associatedtype instead of &lt;T&gt; to define a generic requirement.</p><pre>protocol Container {<br>    associatedtype Item<br>    mutating func add(_ item: Item)<br>    func contains(_ item: Item) -&gt; Bool<br>    var count: Int { get }<br>}<br><br>struct Bag&lt;T: Equatable&gt;: Container {<br>    typealias Item = T<br>    private var items: [T] = []<br>    mutating func add(_ item: T) {<br>        items.append(item)<br>    }<br>    func contains(_ item: T) -&gt; Bool {<br>        items.contains(item)<br>    }<br>    var count: Int { items.count }<br>}<br><br>var bag = Bag&lt;String&gt;()<br>bag.add(&quot;Swift&quot;)<br>bag.add(&quot;Generics&quot;)<br>print(bag.contains(&quot;Swift&quot;))  // true<br>print(bag.count)              // 2</pre><p>Associated types let <a href="https://dkvekariya.medium.com/swift-protocols-contracts-conformance-and-protocol-oriented-programming-6b9d48617970">protocols</a> be generic without the angle bracket syntax. This is how Collection, Sequence, and IteratorProtocol in the standard library are designed.</p><h3>Generic Extensions</h3><p>Add behavior to a generic type conditionally.</p><pre>extension Stack where Element: Equatable {<br>    func contains(_ item: Element) -&gt; Bool {<br>        storage.contains(item)<br>    }<br>}<br><br>extension Stack: CustomStringConvertible where Element: CustomStringConvertible {<br>    var description: String {<br>        &quot;[&quot; + storage.map { $0.description }.joined(separator: &quot;, &quot;) + &quot;]&quot;<br>    }<br>}</pre><p>contains only exists on stacks whose elements are Equatable. description only exists when elements have a string representation. The compiler adds exactly the right capabilities to each concrete type.</p><h3>Real-World Pattern: Generic Network Layer</h3><pre>protocol APIEndpoint {<br>    associatedtype Response: Decodable<br>    var path: String { get }<br>    var method: HTTPMethod { get }<br>}<br><br>struct UsersEndpoint: APIEndpoint {<br>    typealias Response = [User]<br>    var path: String { &quot;/users&quot; }<br>    var method: HTTPMethod { .get }<br>}<br><br>struct CreateOrderEndpoint: APIEndpoint {<br>    typealias Response = Order<br>    var path: String { &quot;/orders&quot; }<br>    var method: HTTPMethod { .post }<br>}<br><br>class APIClient {<br>    func request&lt;E: APIEndpoint&gt;(_ endpoint: E) async throws -&gt; E.Response {<br>        let url = URL(string: baseURL + endpoint.path)!<br>        let (data, _) = try await URLSession.shared.data(from: url)<br>        return try JSONDecoder().decode(E.Response.self, from: data)<br>    }<br>}<br><br>let client = APIClient()<br>let users: [User] = try await client.request(UsersEndpoint())<br>let order: Order = try await client.request(CreateOrderEndpoint())</pre><p>One request function handles every endpoint in the app. The return type is inferred automatically from the endpoint&#39;s associated type. No casting. No Any. Full type safety at every call site.</p><h3>Interview Questions</h3><p><strong>Q: What are generics in Swift and why are they important?</strong></p><p>Generics let you write functions and types that work with any type while preserving full type safety. Without generics, you either duplicate code for each type or lose type safety by using Any. Generics give you both: one implementation and compile-time guarantees. Swift&#39;s Optional, <a href="https://dkvekariya.medium.com/897fb535f805"><strong>Result</strong></a>, Array, Dictionary, and most of the standard library are built on generics. They are the foundation of reusable, type-safe code in Swift.</p><p><strong>Q: What is the difference between a generic type parameter and a protocol associated type?</strong></p><p>A generic type parameter is declared at the point of use with angle brackets: func foo&lt;T&gt;(_ value: T). The caller decides what T is. A protocol associated type is declared inside a protocol with associatedtype. The conforming type decides what the associated type is. Generic parameters are for functions and types you write directly. Associated types are for <a href="https://dkvekariya.medium.com/swift-protocols-contracts-conformance-and-protocol-oriented-programming-6b9d48617970">protocols</a> that need to express relationships between types without specifying them up front.</p><h3>Summary</h3><ul><li>Generics let you write one implementation that works with any type safely.</li><li>Type parameters like &lt;T&gt; are placeholders filled in at the call site.</li><li>Constraints like &lt;T: Comparable&gt; restrict which types are allowed and unlock specific capabilities.</li><li>The where clause adds constraints without cluttering the signature.</li><li><a href="https://dkvekariya.medium.com/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659">Structs</a>, classes, <a href="https://dkvekariya.medium.com/swift-enums-associated-values-raw-values-and-pattern-matching-a5844461beb1">enums</a>, and functions can all be generic.</li><li>Protocol associated types are the protocol-side equivalent of generic type parameters.</li><li>Generic extensions with constraints add behavior only when the element type qualifies.</li><li>The entire Swift standard library and most production network layers are built on generics.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Write a generic pairs&lt;T&gt;(_ array: [T]) -&gt; [(T, T)] function that returns consecutive pairs from an array: [1,2,3,4] becomes [(1,2), (2,3), (3,4)]. Handle arrays with fewer than two elements gracefully.</li><li><strong>Intermediate:</strong> Build a generic Cache&lt;Key: Hashable, Value&gt; struct with set(_ value: Value, for key: Key), get(_ key: Key) -&gt; Value?, and remove(_ key: Key) methods. Add a maxSize: Int parameter that evicts the oldest entry when the cache is full.</li><li><strong>Advanced:</strong> Design a type-safe EventBus&lt;Event&gt; using generics and associated types. Publishers post events of a specific type. Subscribers receive only the event type they registered for. The compiler should prevent subscribing to the wrong event type entirely, with no casting at the call site. Show it working with at least two distinct event types.</li></ol><h3>What’s Next</h3><p><strong>Article 17: Functional Programming in Swift: map, filter, reduce, and Beyond</strong></p><p>Generics make your types flexible. Functional programming makes your logic composable. map, filter, reduce, flatMap, compactMap, and zip are not just collection utilities. They are a fundamentally different way of thinking about data transformation. Once they click, you will find yourself writing cleaner, shorter, and more testable code across every layer of your app.</p><p><em>Part of </em><strong><em>Swift from Zero to Senior</em></strong><em> — a complete iOS engineering curriculum on Medium.</em></p><p><strong>If generics finally make sense as a design tool rather than just syntax, tap 👏 up to 50 times and do 🔁. It helps this series reach developers still copying functions to handle different types.</strong></p><p><strong>Follow me</strong> so Article 17 lands in your feed automatically. Functional programming is next and it pairs perfectly with everything you just learned.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d6640afccdc9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ARC and Memory Management: How Swift Keeps Your App From Leaking]]></title>
            <link>https://dkvekariya.medium.com/arc-and-memory-management-how-swift-keeps-your-app-from-leaking-2e9af2ea677f?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/2e9af2ea677f</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 02 Oct 2026 14:21:01 GMT</pubDate>
            <atom:updated>2026-10-02T14:21:01.492Z</atom:updated>
            <content:encoded><![CDATA[<p><em>Every object in your app has a lifetime. ARC manages it automatically. But automatic does not mean foolproof.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*giuYM4AzNkIAQksWuGUgmQ.png" /></figure><h3>Why Memory Management Matters in Production</h3><p>An app that leaks memory does not crash immediately. It slows down. It gets warm. It consumes more RAM with every navigation until iOS kills it in the background or the user force-quits it in frustration. Memory bugs are silent killers and they are almost always caused by the same small set of patterns.</p><p>Understanding ARC is not optional knowledge for senior iOS engineers. It is foundational.</p><h3>What ARC Does</h3><p><strong>Automatic Reference Counting</strong> tracks how many references point to each class instance. When that count reaches zero, ARC deallocates the object and reclaims the memory.</p><pre>class User {<br>    let name: String<br><br>    init(name: String) {<br>        self.name = name<br>        print(&quot;\(name) initialized&quot;)<br>    }<br>    deinit {<br>        print(&quot;\(name) deallocated&quot;)<br>    }<br>}<br><br>var ref1: User? = User(name: &quot;Aryan&quot;)  // count: 1 - &quot;Aryan initialized&quot;<br>var ref2 = ref1                         // count: 2<br>var ref3 = ref1                         // count: 3<br>ref1 = nil  // count: 2<br>ref2 = nil  // count: 1<br>ref3 = nil  // count: 0 - &quot;Aryan deallocated&quot;</pre><p>ARC runs at compile time, not runtime. It inserts retain and release calls for you. No garbage collector, no pauses, no unpredictable cleanup timing.</p><h3>Strong References: The Default</h3><p>Every regular reference is <strong>strong</strong>. It increments the reference count and keeps the object alive.</p><pre>class Team {<br>    var name: String<br>    init(name: String) { self.name = name }<br>}<br><br>let team = Team(name: &quot;iOS&quot;)  // strong reference - count: 1</pre><p>Most of the time, strong is exactly what you want. The object lives as long as someone holds a reference to it.</p><h3>Retain Cycles: When ARC Gets Stuck</h3><p>A retain cycle happens when two objects hold strong references to each other. Neither count reaches zero. Neither object ever deallocates.</p><pre>class Author {<br>    var name: String<br>    var article: Article?<br><br>    init(name: String) { self.name = name }<br>    deinit { print(&quot;\(name) deallocated&quot;) }<br>}<br><br>class Article {<br>    var title: String<br>    var author: Author?  // strong reference back to Author<br>    init(title: String) { self.title = title }<br>    deinit { print(&quot;\(title) deallocated&quot;) }<br>}<br><br>var author: Author? = Author(name: &quot;Aryan&quot;)<br>var article: Article? = Article(title: &quot;Swift ARC&quot;)<br>author?.article = article  // Author -&gt; Article (strong)<br>article?.author = author   // Article -&gt; Author (strong)<br>author = nil   // Author count: still 1 (Article holds it)<br>article = nil  // Article count: still 1 (Author holds it)<br>// deinit never called - both objects leak</pre><p>Two objects, each keeping the other alive. The external references are gone but the cycle keeps both counts above zero forever.</p><h3>Weak References: Breaking the Cycle</h3><p>A <strong>weak</strong> reference does not increment the reference count. It does not keep the object alive. If the object deallocates, the weak reference automatically becomes nil.</p><pre>class Article {<br>    var title: String<br>    weak var author: Author?  // weak — does not keep Author alive<br>    init(title: String) { self.title = title }<br>    deinit { print(&quot;\(title) deallocated&quot;) }<br>}<br><br>var author: Author? = Author(name: &quot;Aryan&quot;)<br>var article: Article? = Article(title: &quot;Swift ARC&quot;)<br>author?.article = article<br>article?.author = author<br>author = nil   // Author count: 0 - &quot;Aryan deallocated&quot;<br>article = nil  // Article count: 0 - &quot;Swift ARC deallocated&quot;</pre><p>Cycle broken. Both objects deallocate cleanly.</p><p>Weak references must be var and optional. They can become nil at any time, so the compiler requires you to treat them as Optional.</p><h3>Unowned References: The Riskier Option</h3><p>An <strong>unowned</strong> reference also does not increment the reference count. The difference: it does not become nil when the object deallocates. Accessing an unowned reference after deallocation crashes the app.</p><pre>class Customer {<br>    var name: String<br>    var card: CreditCard?<br>    init(name: String) { self.name = name }<br>    deinit { print(&quot;\(name) deallocated&quot;) }<br>}<br><br>class CreditCard {<br>    let number: String<br>    unowned let customer: Customer  // card cannot outlive the customer<br>    init(number: String, customer: Customer) {<br>        self.number = number<br>        self.customer = customer<br>    }<br>    deinit { print(&quot;Card \(number) deallocated&quot;) }<br>}<br><br>var customer: Customer? = Customer(name: &quot;Aryan&quot;)<br>customer?.card = CreditCard(number: &quot;4111&quot;, customer: customer!)<br>customer = nil<br>// &quot;Aryan deallocated&quot;<br>// &quot;Card 4111 deallocated&quot;</pre><p>Use unowned only when you are certain the referenced object will always outlive the referencing one. If there is any doubt, use weak. A crash from an invalid unowned reference is harder to diagnose than an unexpected nil.</p><h3>The Closure Retain Cycle</h3><p><a href="https://medium.com/@dkvekariya/swift-closures-the-concept-that-unlocks-everything-else-91d441e21f24"><strong>Closures</strong></a> are the most common source of retain cycles in real iOS code. A closure stored as a property captures self strongly by default. If self also holds the closure, you have a cycle.</p><pre>class VideoPlayer {<br>    var onPlaybackEnd: (() -&gt; Void)?<br><br>    func setup() {<br>        onPlaybackEnd = {<br>            self.reset()  // strong capture of self<br>        }<br>        // VideoPlayer holds onPlaybackEnd<br>        // onPlaybackEnd holds VideoPlayer<br>        // cycle<br>    }<br><br>    func reset() { }<br>    deinit { print(&quot;VideoPlayer deallocated&quot;) }<br>}</pre><p>Fix with a capture list:</p><pre>onPlaybackEnd = { [weak self] in<br>    self?.reset()<br>}</pre><p>This is the pattern from <a href="https://medium.com/@dkvekariya/swift-closures-the-concept-that-unlocks-everything-else-91d441e21f24"><strong>Article 7 (Closures)</strong></a> viewed through the lens of ARC. The capture list makes the closure’s reference to self weak. The cycle breaks. self deallocates when its external references are gone.</p><h3>Finding Leaks with Instruments</h3><p>Xcode’s Memory Graph Debugger is your first tool for finding retain cycles:</p><ol><li>Run your app in Xcode</li><li>Navigate to the screen you suspect is leaking</li><li>Navigate away</li><li>Click the Memory Graph button in the Debug bar</li><li>Look for objects that should have deallocated but still appear in the graph</li></ol><p>Instruments’ Leaks and Allocations templates go deeper for production profiling. Any object shown in the memory graph after it should have been released is a candidate for investigation.</p><h3>Real-World Patterns That Leak (and Their Fixes)</h3><p><strong>Timer retain cycle:</strong></p><pre>// Leak — Timer holds a strong reference to self<br>class ClockView {<br>    var timer: Timer?<br><br>    func start() {<br>        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in<br>            self.updateDisplay()  // strong capture<br>        }<br>    }<br>}<br><br>// Fix<br>timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in<br>    self?.updateDisplay()<br>}</pre><p><strong>Delegate retain cycle:</strong></p><pre>// Leak — strong delegate creates a cycle<br>class DataLoader {<br>    var delegate: DataLoaderDelegate?  // strong<br>}<br><br>// Fix - delegates are almost always weak<br>class DataLoader {<br>    weak var delegate: DataLoaderDelegate?<br>}</pre><p><strong>NotificationCenter observer not removed:</strong></p><pre>// Leak in older APIs — observer not removed<br>class ViewController: UIViewController {<br>    override func viewDidLoad() {<br>        NotificationCenter.default.addObserver(<br>            self,<br>            selector: #selector(handleUpdate),<br>            name: .dataUpdated,<br>            object: nil<br>        )<br>    }<br>    // Fix: remove in deinit or use the block-based API with [weak self]<br>    deinit {<br>        NotificationCenter.default.removeObserver(self)<br>    }<br>}</pre><h3>Interview Questions</h3><p><strong>Q: What is a retain cycle and how do you fix one in Swift?</strong></p><p>A retain cycle occurs when two or more objects hold strong references to each other, preventing ARC from ever reducing either object’s reference count to zero. Both objects leak. The fix is to break the cycle by making one reference weak or unowned. Use weak when the referenced object can outlive the referencing one and may become nil. Use unowned only when you can guarantee the referenced object always outlives the referencing one.</p><p><strong>Q: What is the difference between weak and unowned in Swift?</strong></p><p>Both are non-retaining references that do not increment ARC’s reference count. weak is always optional and automatically becomes nil when the referenced object deallocates. unowned is non-optional and does not become nil. Accessing an unowned reference after the object deallocates causes a crash. Use weak when the referenced object might deallocate before the referencing one. Use unowned when you can guarantee it will not.</p><h3>Summary</h3><ul><li>ARC automatically tracks reference counts for class instances and deallocates them at zero.</li><li>Strong references are the default and keep objects alive.</li><li>Retain cycles occur when objects hold strong references to each other, preventing deallocation.</li><li>weak references do not retain, are always optional, and become nil on deallocation.</li><li>unowned references do not retain and are non-optional. Accessing them after deallocation crashes.</li><li>Closures capture self strongly by default. Use [weak self] capture lists to break cycles.</li><li>Delegates should almost always be weak.</li><li>Timers, notification observers, and stored closures are the most common real-world leak sources.</li><li>Use Xcode’s Memory Graph Debugger and Instruments to detect leaks before they reach production.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Create two <a href="https://medium.com/@dkvekariya/swift-classes-reference-types-inheritance-and-when-to-use-them-f7a1fd4bd47c"><strong>classes</strong></a>, Parent and Child, where Parent has a strong reference to Child and Child has a strong reference back to Parent. Add deinit to both and verify they never print. Then fix the cycle using weak and verify both deinit calls fire.</li><li><strong>Intermediate:</strong> Build a EventBus class that stores an array of closures as subscribers. Show how a subscriber that captures self strongly creates a leak when the subscribing object deallocates. Fix it using [weak self] and clean up nil subscribers from the array automatically.</li><li><strong>Advanced:</strong> Profile a UIViewController subclass in Instruments that has a retain cycle caused by a Timer and a stored closure. Document exactly which reference is causing the cycle, fix it, and verify the deallocation in the Memory Graph Debugger. Write a brief post-mortem explaining the root cause, the fix, and the general rule it illustrates.</li></ol><h3>What’s Next</h3><p><strong>Article 16: Swift Generics: Write Once, Use Everywhere</strong></p><p>ARC taught you how Swift manages the lifetime of objects in memory. Generics teach you how to write code that works across types without duplicating logic. They are the foundation of Swift’s collections, Result, Optional, and almost every reusable component you will ever build.</p><p><em>Part of </em><strong><em>Swift from Zero to Senior</em></strong><em> — a complete iOS engineering curriculum on Medium.</em></p><p><strong>If ARC finally clicked and you can see where your app might be leaking, tap 👏 up to 50 times. It helps this series reach developers shipping apps with silent memory bugs.</strong></p><p><strong>Follow me</strong> so Article 16 lands in your feed automatically. Generics are next and they will change how you write reusable code forever.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2e9af2ea677f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift Error Handling: throw, try, catch, and Result]]></title>
            <link>https://dkvekariya.medium.com/swift-error-handling-throw-try-catch-and-result-897fb535f805?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/897fb535f805</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 25 Sep 2026 14:11:01 GMT</pubDate>
            <atom:updated>2026-09-25T14:11:01.534Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Swift forces you to acknowledge every failure path before your code builds. That is not a restriction. It is a feature.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LGNGFcp3UomCKCcKVQTpCw.png" /></figure><h3>Why Error Handling Is Not Optional</h3><p>Every app fails sometimes. Networks go down. Files go missing. Users enter bad data. JSON arrives malformed. The question is never whether your app will encounter errors. It is whether your code handles them deliberately or discovers them as crashes.</p><p>Swift’s error system makes deliberate handling the only option. If a function can throw, the compiler forces you to acknowledge that before your code builds. You cannot forget. You cannot ignore it. That guarantee is worth more than it might seem.</p><h3>Defining Errors</h3><p>Swift errors conform to the Error <a href="https://medium.com/@dkvekariya/swift-protocols-contracts-conformance-and-protocol-oriented-programming-6b9d48617970"><strong>protocol</strong></a>. Enums are the natural fit because they enumerate exactly what can go wrong.</p><pre>enum NetworkError: Error {<br>    case invalidURL<br>    case noConnection<br>    case timeout(after: TimeInterval)<br>    case serverError(statusCode: Int)<br>    case decodingFailed(reason: String)<br>}</pre><p>Each case is a distinct, named failure. No integer error codes. No string comparisons. The compiler knows every possible error at compile time.</p><h3>Throwing Functions</h3><p>Mark a function with throws to indicate it can fail.</p><pre>func fetchUser(id: String) throws -&gt; User {<br>    guard !id.isEmpty else {<br>        throw NetworkError.invalidURL<br>    }<br>    <br>    // Simulate fetch<br>    guard let user = database[id] else {<br>        throw NetworkError.serverError(statusCode: 404)<br>    }<br>    return user<br>}</pre><p>The throws keyword is part of the function signature. Any caller can see at a glance that this function might fail.</p><h3>Calling Throwing Functions</h3><p>You must use try when calling a throwing function. Then handle the error with do/catch.</p><pre>do {<br>    let user = try fetchUser(id: &quot;usr_001&quot;)<br>    print(&quot;Found: \(user.name)&quot;)<br>} catch NetworkError.invalidURL {<br>    print(&quot;The URL was invalid&quot;)<br>} catch NetworkError.serverError(let code) {<br>    print(&quot;Server returned \(code)&quot;)<br>} catch NetworkError.timeout(let seconds) {<br>    print(&quot;Request timed out after \(seconds)s&quot;)<br>} catch {<br>    // Catches everything else<br>    print(&quot;Unexpected error: \(error)&quot;)<br>}</pre><p>Swift’s catch supports full pattern matching, including associated values. The final bare catch is your safety net for anything you did not explicitly anticipate.</p><h3>try? and try!</h3><p>Two shorthand options when you need less ceremony.</p><pre>// try? — converts the result to Optional, nil on failure<br>let user = try? fetchUser(id: &quot;usr_001&quot;)<br>// user is User? — nil if fetchUser threw anything<br><br>// try! - force unwraps the result, crashes if it throws<br>let user = try! fetchUser(id: &quot;usr_001&quot;)<br>// Crashes at runtime if fetchUser throws</pre><p>try? is useful when failure is acceptable and you just want a nil. Loading a cached image, for example. If the cache misses, nil is fine.</p><p>try! is the same risk as force-unwrapping an <a href="https://medium.com/@dkvekariya/swift-optionals-nil-unwrapping-and-the-safety-system-behind-the-24d48687694f"><strong>optional</strong></a>. Use it only when you are certain the function cannot throw in this context, and document why.</p><h3>Propagating Errors</h3><p>Throwing functions can propagate errors up the call stack instead of handling them immediately. Mark the caller as throws too.</p><pre>func loadUserProfile(id: String) throws -&gt; UserProfile {<br>    let user = try fetchUser(id: id)       // propagates if this throws<br>    let posts = try fetchPosts(for: user)  // propagates if this throws<br>    return UserProfile(user: user, posts: posts)<br>}</pre><p>The error bubbles up until something catches it. This lets you handle errors at the right layer instead of wrapping every function call in do/catch.</p><h3>Result&lt;Success, Failure&gt;: Errors as Values</h3><p>Result is Swift&#39;s enum for representing success or failure as a value rather than through throwing.</p><pre>enum Result&lt;Success, Failure: Error&gt; {<br>    case success(Success)<br>    case failure(Failure)<br>}</pre><p>Use it when you need to store an error, pass it to a completion handler, or work with APIs that use callbacks instead of async/await.</p><pre>func fetchUser(id: String, completion: @escaping (Result&lt;User, NetworkError&gt;) -&gt; Void) {<br>    guard !id.isEmpty else {<br>        completion(.failure(.invalidURL))<br>        return<br>    }<br><br>    // Simulate async fetch<br>    DispatchQueue.global().asyncAfter(deadline: .now() + 1) {<br>        if let user = self.database[id] {<br>            completion(.success(user))<br>        } else {<br>            completion(.failure(.serverError(statusCode: 404)))<br>        }<br>    }<br>}<br><br>// Call site<br>fetchUser(id: &quot;usr_001&quot;) { result in<br>    switch result {<br>    case .success(let user):<br>        print(&quot;Loaded: \(user.name)&quot;)<br>    case .failure(let error):<br>        print(&quot;Failed: \(error)&quot;)<br>    }<br>}</pre><p>Result makes the success and failure paths explicit and equal. No hidden <a href="https://medium.com/@dkvekariya/swift-optionals-nil-unwrapping-and-the-safety-system-behind-the-24d48687694f"><strong>optional</strong></a>, no separate error parameter.</p><h3>Converting Between throws and Result</h3><p>Swift makes this seamless.</p><pre>// throws -&gt; Result<br>let result = Result { try fetchUser(id: &quot;usr_001&quot;) }<br><br>// Result -&gt; throws<br>let user = try result.get()</pre><p>Result { } captures any thrown error into .failure. .get() throws the failure back out. Use whichever style fits the surrounding code.</p><h3>rethrows: Conditional Throwing</h3><p>A function marked rethrows only throws if one of its closure parameters throws.</p><pre>func transform&lt;T&gt;(_ values: [T], using block: (T) throws -&gt; T) rethrows -&gt; [T] {<br>    try values.map(block)<br>}<br><br>// Non-throwing closure - transform doesn&#39;t throw<br>let doubled = transform([1, 2, 3]) { $0 * 2 }<br>// Throwing closure - transform can throw<br>let parsed = try transform([&quot;1&quot;, &quot;two&quot;, &quot;3&quot;]) { str in<br>    guard let int = Int(str) else { throw ParseError.invalid(str) }<br>    return int<br>}</pre><p>rethrows is how map, filter, and forEach in the standard library work. They only require try when the closure you pass them throws.</p><h3>Real-World Pattern: Layered Error Handling</h3><p>Production apps translate low-level errors into user-facing messages at the right layer.</p><pre>enum AppError: Error, LocalizedError {<br>    case networkUnavailable<br>    case sessionExpired<br>    case contentNotFound<br>    case unknown(Error)<br><br>    var errorDescription: String? {<br>        switch self {<br>        case .networkUnavailable:  return &quot;Check your internet connection and try again.&quot;<br>        case .sessionExpired:      return &quot;Your session has expired. Please log in again.&quot;<br>        case .contentNotFound:     return &quot;This content is no longer available.&quot;<br>        case .unknown:             return &quot;Something went wrong. Please try again.&quot;<br>        }<br>    }<br>}<br><br>func mapToAppError(_ error: Error) -&gt; AppError {<br>    guard let networkError = error as? NetworkError else {<br>        return .unknown(error)<br>    }<br>    switch networkError {<br>    case .noConnection:            return .networkUnavailable<br>    case .serverError(401):        return .sessionExpired<br>    case .serverError(404):        return .contentNotFound<br>    default:                       return .unknown(error)<br>    }<br>}</pre><p>Low-level network errors stay in the networking layer. The app layer speaks in user-friendly terms. The view just reads errorDescription and displays it. Each layer handles what it knows about.</p><h3>Interview Questions</h3><p><strong>Q: What is the difference between </strong><strong>throws and </strong><strong>Result in Swift error handling?</strong></p><p>throws uses Swift&#39;s built-in error propagation mechanism. The compiler forces callers to use try and either handle or propagate the error. Result represents success or failure as a value in an enum. Use throws for synchronous code and async/await-based APIs where the compiler can enforce error handling directly. Use Result for completion handler-based APIs, when you need to store or pass an error as a value, or when working with older callback-based code.</p><p><strong>Q: What does </strong><strong>rethrows mean in Swift?</strong></p><p>rethrows marks a function that only throws if one of the closure parameters it receives throws. If you pass a non-throwing closure, the function itself does not throw and no try is needed at the call site. If you pass a throwing closure, the function can rethrow that error. This is how standard library functions like map and filter work cleanly with both throwing and non-throwing closures.</p><h3>Summary</h3><ul><li>Swift errors conform to Error. <a href="https://medium.com/@dkvekariya/swift-enums-associated-values-raw-values-and-pattern-matching-a5844461beb1"><strong>Enums with associated values</strong></a> are the cleanest modeling tool.</li><li>throws in a function signature tells every caller: this can fail.</li><li>do/catch handles errors with full pattern matching, including associated values.</li><li>try? converts failure to nil. try! crashes on failure. Use both sparingly.</li><li>Errors propagate up the call stack until something catches them.</li><li>Result&lt;Success, Failure&gt; represents success or failure as a value, ideal for completion handlers.</li><li>Result { try... } captures thrown errors. .get() throws them back out.</li><li>rethrows only propagates errors when a closure parameter itself throws.</li><li>Translate low-level errors into user-facing messages at the appropriate architectural layer.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Create a divide(_ a: Double, by b: Double) throws -&gt; Double function that throws a MathError.divisionByZero case when b is zero. Call it with do/catch, with try?, and with try!. Explain when each is appropriate.</li><li><strong>Intermediate:</strong> Build a JSONLoader struct with a load&lt;T: Decodable&gt;(_ filename: String) throws -&gt; T method that reads a JSON file from the app bundle and decodes it. Define a FileError enum covering file not found, read failure, and decoding failure with associated error messages. Chain the error propagation correctly so callers see meaningful errors.</li><li><strong>Advanced:</strong> Create a Validator&lt;T&gt; struct that takes an array of (T) throws -&gt; Void validation rules. Add a validate(_ value: T) -&gt; Result&lt;T, ValidationError&gt; method where ValidationError collects all failures, not just the first one. Use rethrows where appropriate and write a concrete example validating a RegistrationForm struct with rules for username length, email format, and password strength.</li></ol><h3>What’s Next</h3><p><strong>Article 15: ARC and Memory Management: How Swift Keeps Your App From Leaking</strong></p><p>You now know how Swift handles errors at the language level. Next: how it handles memory. Automatic Reference Counting is what keeps your objects alive exactly as long as they need to be and no longer. Understanding ARC, strong references, weak references, and retain cycles is what separates developers who write leak-free apps from those who find memory problems in production.</p><p><em>Part of </em><strong><em>Swift from Zero to Senior</em></strong><em> — a complete iOS engineering curriculum on Medium.</em></p><p><strong>If Swift’s error system just made your failure handling more intentional, tap 👏 up to 50 times and do 🔁. It helps this series reach developers still using </strong><a href="https://medium.com/@dkvekariya/swift-optionals-nil-unwrapping-and-the-safety-system-behind-the-24d48687694f"><strong>optional</strong></a><strong> returns where errors belong.</strong></p><p><strong>Follow me</strong> so Article 15 lands in your feed automatically. Memory management is next and it is one of the most important topics for shipping stable iOS apps.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=897fb535f805" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift Extensions: Add Behavior to Any Type Without Subclassing]]></title>
            <link>https://dkvekariya.medium.com/swift-extensions-add-behavior-to-any-type-without-subclassing-de5090ae3808?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/de5090ae3808</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 18 Sep 2026 14:11:01 GMT</pubDate>
            <atom:updated>2026-09-18T14:11:01.372Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>You can extend String, Int, UIView, or your own types. No subclass needed. No source access required.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lB7hiIeeSxK9O0L7WXPrwQ.png" /></figure><h3>Why Extensions Are One of Swift’s Best Features</h3><p>Most languages let you add behavior to a type by subclassing it or modifying it directly. Swift offers a third path: extend any type, anywhere, without touching the original source.</p><p>You can add methods to String. <a href="https://medium.com/@dkvekariya/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659">Computed properties</a> to Int. <a href="https://medium.com/@dkvekariya/swift-protocols-contracts-conformance-and-protocol-oriented-programming-6b9d48617970"><strong>Protocol conformances</strong></a> to types from third-party libraries. Namespace your own code into focused, readable chunks. Extensions make all of this clean and compiler-safe.</p><h3>The Basics</h3><pre>extension String {<br>    func trimmed() -&gt; String {<br>        trimmingCharacters(in: .whitespacesAndNewlines)<br>    }<br>    <br>    var isBlank: Bool {<br>        trimmed().isEmpty<br>    }<br>}<br><br>let input = &quot;  hello  &quot;<br>print(input.trimmed())  // &quot;hello&quot;<br>print(input.isBlank)    // false<br>print(&quot;   &quot;.isBlank)    // true</pre><p>Every String in your entire project now has trimmed() and isBlank. No subclass, no wrapper type, no helper function hidden in a utility file.</p><h3>What You Can Add in an Extension</h3><p>Extensions support a wide range of additions:</p><pre>extension SomeType {<br>    // Computed properties (stored properties are not allowed)<br>    var computedValue: Int { ... }<br><br>    // Methods<br>    func doSomething() { ... }<br>    // Initializers (convenience, not designated for classes)<br>    init(someParam: String) { ... }<br>    // Subscripts<br>    subscript(key: String) -&gt; String? { ... }<br>    // Nested types<br>    enum State { case active, inactive }<br>}</pre><p>One important limit: extensions cannot add <strong>stored properties</strong>. You can add <a href="https://medium.com/@dkvekariya/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659">computed properties</a> that derive their value, but you cannot add new memory to an existing type from outside its definition.</p><h3>Extending Your Own Types for Organization</h3><p>Extensions are not just for adding new behavior to foreign types. They are one of the cleanest ways to organize your own code.</p><pre>struct UserViewModel {<br>    let user: User<br>    var isLoading: Bool<br>    var errorMessage: String?<br>}<br><br>// Core data<br>extension UserViewModel {<br>    var displayName: String {<br>        user.name.isEmpty ? &quot;Anonymous&quot; : user.name<br>    }<br>    var avatarInitials: String {<br>        String(user.name.prefix(2)).uppercased()<br>    }<br>}<br>// Actions<br>extension UserViewModel {<br>    mutating func refresh() {<br>        isLoading = true<br>        errorMessage = nil<br>    }<br>    mutating func handleError(_ error: Error) {<br>        isLoading = false<br>        errorMessage = error.localizedDescription<br>    }<br>}</pre><p>Split by responsibility, not by arbitrary line count. Each extension block has one clear purpose. New team members find what they need faster.</p><h3>Protocol Conformance in Separate Extensions</h3><p>This is the pattern you will see in every serious Swift codebase.</p><pre>struct Product {<br>    let id: String<br>    let name: String<br>    let price: Double<br>}<br><br>// Core type stays clean<br>// Conformances are declared separately<br>extension Product: Equatable {<br>    static func == (lhs: Product, rhs: Product) -&gt; Bool {<br>        lhs.id == rhs.id<br>    }<br>}<br><br>extension Product: Comparable {<br>    static func &lt; (lhs: Product, rhs: Product) -&gt; Bool {<br>        lhs.price &lt; rhs.price<br>    }<br>}<br><br>extension Product: CustomStringConvertible {<br>    var description: String {<br>        &quot;\(name) - $\(String(format: &quot;%.2f&quot;, price))&quot;<br>    }<br>}</pre><p>Each conformance lives in its own extension block. When you search for “Equatable” in your file, you find it immediately. When you delete a conformance, you delete one focused block, not lines scattered through the original type.</p><h3>Extending Apple’s Types</h3><p>This is where extensions genuinely change how you write daily code.</p><pre>extension Int {<br>    var isEven: Bool { self % 2 == 0 }<br>    var isOdd: Bool { !isEven }<br>    <br>    func times(_ action: () -&gt; Void) {<br>        for _ in 0..&lt;self { action() }<br>    }<br>}<br><br>5.times { print(&quot;hello&quot;) }  // prints &quot;hello&quot; 5 times<br>print(4.isEven)              // true<br><br>extension Double {<br>    var asPercentage: String {<br>        String(format: &quot;%.1f%%&quot;, self * 100)<br>    }<br>}<br><br>print(0.856.asPercentage)  // &quot;85.6%&quot;<br><br>extension Array {<br>    func chunked(into size: Int) -&gt; [[Element]] {<br>        stride(from: 0, to: count, by: size).map {<br>            Array(self[$0..&lt;Swift.min($0 + size, count)])<br>        }<br>    }<br>}<br><br>let pages = [1,2,3,4,5,6,7].chunked(into: 3)<br>// [[1,2,3], [4,5,6], [7]]<br><br>extension Optional where Wrapped == String {<br>    var orEmpty: String {<br>        self ?? &quot;&quot;<br>    }<br>}<br><br>let name: String? = nil<br>print(name.orEmpty)  // &quot;&quot;</pre><p>These are not clever tricks. They are the kind of extensions that end up in every production iOS codebase because they eliminate repetitive unwrapping and formatting code across hundreds of files.</p><h3>Extensions with Constraints</h3><p>You can limit an extension to only apply when generic type parameters meet a condition.</p><pre>extension Array where Element: Numeric {<br>    var sum: Element {<br>        reduce(0, +)<br>    }<br>    <br>    var average: Double {<br>        guard !isEmpty else { return 0 }<br>        return Double(sum as! Double) / Double(count)<br>    }<br>}<br><br>[1, 2, 3, 4, 5].sum  // 15</pre><p>Or for your own generic types:</p><pre>extension Stack where T: Equatable {<br>    func contains(_ value: T) -&gt; Bool {<br>        storage.contains(value)<br>    }<br>}</pre><p>The contains method only exists when the stack holds Equatable elements. The compiler enforces this. You don&#39;t need runtime checks.</p><h3>What Extensions Cannot Do</h3><p>A few limits worth knowing upfront:</p><pre>extension String {<br>    // ❌ Cannot add stored properties<br>    var someStoredValue: Int = 0<br><br>    // ❌ Cannot override existing methods (use subclassing for that)<br>    // override func hasPrefix(_ prefix: String) -&gt; Bool { ... }<br>}</pre><p>Extensions also cannot add designated initializers to classes or add deinit. These rules keep extensions predictable: they add to a type, they don&#39;t restructure it.</p><h3>Real-World Pattern: UIColor Extension</h3><pre>extension UIColor {<br>    convenience init(hex: String) {<br>        var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines)<br>        hexSanitized = hexSanitized.replacingOccurrences(of: &quot;#&quot;, with: &quot;&quot;)<br>      <br>        var rgb: UInt64 = 0<br>        Scanner(string: hexSanitized).scanHexInt64(&amp;rgb)<br>        let r = CGFloat((rgb &amp; 0xFF0000) &gt;&gt; 16) / 255<br>        let g = CGFloat((rgb &amp; 0x00FF00) &gt;&gt; 8) / 255<br>        let b = CGFloat(rgb &amp; 0x0000FF) / 255<br>        self.init(red: r, green: g, blue: b, alpha: 1)<br>    }<br><br>    static let brandPrimary = UIColor(hex: &quot;#4A90E2&quot;)<br>    static let brandSecondary = UIColor(hex: &quot;#F5A623&quot;)<br>}<br><br>// Usage<br>view.backgroundColor = .brandPrimary<br>label.textColor = UIColor(hex: &quot;#333333&quot;)</pre><p>This is a convenience initializer added to UIColor from Apple&#39;s UIKit. You cannot modify UIKit&#39;s source. Extensions make this possible cleanly.</p><h3>Interview Questions</h3><p><strong>Q: What can and cannot be added to a type via an extension in Swift?</strong></p><p>Extensions can add <a href="https://medium.com/@dkvekariya/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659"><strong>computed properties</strong></a>, methods, initializers (convenience initializers for classes), subscripts, nested types, and <a href="https://medium.com/@dkvekariya/swift-protocols-contracts-conformance-and-protocol-oriented-programming-6b9d48617970"><strong>protocol conformances</strong></a>. They cannot add stored properties, cannot override existing implementations (that requires subclassing), and cannot add designated initializers or deinit to classes. The constraint on stored properties exists because extensions cannot change the memory layout of a type defined elsewhere.</p><p><strong>Q: Why do senior Swift engineers put protocol conformances in separate extension blocks?</strong></p><p>Separating conformances into distinct extensions makes each one easy to find, reason about, and delete independently. When you search for Equatable conformance, you find one focused block rather than code scattered through the main type definition. It also makes code review cleaner: a diff that adds Codable conformance via an extension is immediately understandable without reading the entire type.</p><h3>Summary</h3><ul><li>Extensions add <a href="https://medium.com/@dkvekariya/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659"><strong>computed properties</strong></a>, methods, initializers, subscripts, and <a href="https://medium.com/@dkvekariya/swift-protocols-contracts-conformance-and-protocol-oriented-programming-6b9d48617970"><strong>protocol conformances</strong></a> to any type.</li><li>Extensions cannot add stored properties or override existing methods.</li><li>Organizing your own types into focused extension blocks by responsibility improves readability and navigation.</li><li><a href="https://medium.com/@dkvekariya/swift-protocols-contracts-conformance-and-protocol-oriented-programming-6b9d48617970"><strong>Protocol conformances</strong></a> in separate extension blocks make each conformance easy to find and remove.</li><li>Constrained extensions apply only when generic parameters meet specific requirements.</li><li>Extensions on Apple’s types like String, Array, and UIColor eliminate repetitive utility code across a codebase.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Write extensions on String for isValidEmail: Bool (basic format check), wordCount: Int, and capitalizingFirstLetter() -&gt; String. Use them in a form validation function.</li><li><strong>Intermediate:</strong> Extend Array with three useful methods: second: Element? (returns the second element safely), groupedBy&lt;Key: Hashable&gt;(_ keyPath: KeyPath&lt;Element, Key&gt;) -&gt; [Key: [Element]], and removingDuplicates() -&gt; [Element] where Element: Equatable. Write tests for each.</li><li><strong>Advanced:</strong> Create a UserDefaults extension that uses a generic subscript with Codable constraints to read and write any Codable type. Use @propertyWrapper style with a custom Persisted&lt;T: Codable&gt; wrapper that reads from and writes to UserDefaults automatically. Show how it eliminates boilerplate compared to raw UserDefaults usage.</li></ol><h3>What’s Next</h3><p><strong>Article 14: Swift Error Handling: throw, try, catch, and Result</strong></p><p>Extensions make your types richer. Error handling makes them honest. Swift’s error system is not just try/catch ported from other languages. It is a compile-enforced mechanism that forces you to acknowledge every failure path before your code builds. Combined with Result&lt;T, Error&gt;, it becomes one of the cleanest error propagation systems in any modern language.</p><p><em>Part of </em><strong><em>Swift from Zero to Senior</em></strong><em> — a complete iOS engineering curriculum on Medium.</em></p><p><strong>If extensions changed how you think about organizing code, tap 👏 up to 50 times. It helps this series reach developers still writing utility helper files full of free functions.</strong></p><p><strong>Follow me</strong> so Article 14 lands in your feed the moment it goes live. Error handling is next and it is far more powerful than most developers realize.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=de5090ae3808" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift Protocols: Contracts, Conformance, and Protocol-Oriented Programming]]></title>
            <link>https://dkvekariya.medium.com/swift-protocols-contracts-conformance-and-protocol-oriented-programming-6b9d48617970?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/6b9d48617970</guid>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 11 Sep 2026 07:31:02 GMT</pubDate>
            <atom:updated>2026-09-11T07:31:02.117Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Classes give you inheritance. Protocols give you composition. One scales. One doesn’t.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*X8Wem04aXAO06WPI-KGPvg.png" /></figure><h3>Why Protocols Change Everything</h3><p>Swift is not an object-oriented language at heart. It is a protocol-oriented one. Apple said this at WWDC 2015 and then proceeded to build SwiftUI, Combine, and the entire standard library around it.</p><p>Understanding protocols is the difference between writing code that works and writing code that scales, composes, and stays testable as your app grows.</p><h3>What Is a Protocol?</h3><p>A protocol defines a contract. It says: “Any type that conforms to me must provide these properties and methods.” It says nothing about how they’re implemented.</p><pre>protocol Greetable {<br>    var name: String { get }<br>    func greet() -&gt; String<br>}</pre><p>Any struct, class, or enum can conform:</p><pre>struct User: Greetable {<br>    var name: String<br><br>    func greet() -&gt; String {<br>        &quot;Hello, I&#39;m \(name)&quot;<br>    }<br>}<br><br>struct Bot: Greetable {<br>    var name: String<br>    func greet() -&gt; String {<br>        &quot;BEEP. I AM \(name.uppercased()). BOOP.&quot;<br>    }<br>}</pre><p>Both types are Greetable. Both implement greet() differently. Code that accepts a Greetable works with either, without knowing which one it has.</p><h3>Protocol Properties</h3><p>Protocols specify whether a property must be gettable, settable, or both.</p><pre>protocol Vehicle {<br>    var speed: Double { get }        // read-only minimum requirement<br>    var fuelLevel: Double { get set } // must be read-write<br>    var description: String { get }<br>}</pre><p>A conforming type can satisfy { get } with either a stored property or a computed one. It must satisfy { get set } with a mutable stored property.</p><pre>struct Car: Vehicle {<br>    var speed: Double          // stored — satisfies { get }<br>    var fuelLevel: Double      // stored — satisfies { get set }<br><br>    var description: String {  // computed - also satisfies { get }<br>        &quot;Car going \(speed) km/h&quot;<br>    }<br>}</pre><h3>Default Implementations with Extensions</h3><p>Protocol extensions let you provide default behavior. Conforming types get it for free and can override it if needed.</p><pre>protocol Describable {<br>    var name: String { get }<br>    func describe() -&gt; String<br>}<br><br>extension Describable {<br>    func describe() -&gt; String {<br>        &quot;I am \(name)&quot;  // default implementation<br>    }<br>}<br>struct Product: Describable {<br>    var name: String<br>    // describe() is provided automatically<br>}<br>struct SpecialProduct: Describable {<br>    var name: String<br>    func describe() -&gt; String {<br>        &quot;Special: \(name)&quot;  // overrides the default<br>    }<br>}<br>print(Product(name: &quot;Laptop&quot;).describe())         // I am Laptop<br>print(SpecialProduct(name: &quot;Laptop&quot;).describe())  // Special: Laptop</pre><p>This is one of the most powerful patterns in Swift. Add behavior to a protocol once and every conforming type benefits. No inheritance required.</p><h3>Protocol Composition</h3><p>A type can conform to multiple protocols. You can also require multiple protocols at once using &amp;.</p><pre>protocol Flyable {<br>    func fly()<br>}<br><br>protocol Swimmable {<br>    func swim()<br>}<br>struct Duck: Flyable, Swimmable {<br>    func fly() { print(&quot;Flap flap&quot;) }<br>    func swim() { print(&quot;Splash splash&quot;) }<br>}<br>func demonstrate(_ animal: Flyable &amp; Swimmable) {<br>    animal.fly()<br>    animal.swim()<br>}<br>demonstrate(Duck())</pre><p>This is composition over inheritance. Instead of building a class hierarchy to represent a flying, swimming animal, you compose behaviors from focused protocols. Adding a Walkable protocol later doesn&#39;t require restructuring anything.</p><h3>Using Protocols as Types</h3><p>Protocols are first-class types. You can use them as parameter types, return types, and stored properties.</p><pre>protocol Shape {<br>    var area: Double { get }<br>}<br><br>struct Circle: Shape {<br>    var radius: Double<br>    var area: Double { .pi * radius * radius }<br>}<br>struct Rectangle: Shape {<br>    var width: Double<br>    var height: Double<br>    var area: Double { width * height }<br>}<br>func totalArea(of shapes: [Shape]) -&gt; Double {<br>    shapes.reduce(0) { $0 + $1.area }<br>}<br>let shapes: [Shape] = [Circle(radius: 5), Rectangle(width: 4, height: 6)]<br>print(totalArea(of: shapes))  // 102.53...</pre><p>The function doesn’t know or care whether each shape is a Circle or Rectangle. It just knows they&#39;re Shape. This is <strong>polymorphism without inheritance</strong>.</p><h3>Equatable, Comparable, Hashable: The Standard Protocols</h3><p>Swift’s standard library is built on protocols. Three you’ll use constantly:</p><pre>struct User: Equatable, Comparable, Hashable {<br>    let id: String<br>    var name: String<br><br>// Equatable - compiler synthesizes == for you if all properties are Equatable<br>    // Hashable - compiler synthesizes hash(into:) for you<br>    // Comparable - you provide this one<br>    static func &lt; (lhs: User, rhs: User) -&gt; Bool {<br>        lhs.name &lt; rhs.name<br>    }<br>}<br>let users = [User(id: &quot;2&quot;, name: &quot;Riya&quot;), User(id: &quot;1&quot;, name: &quot;Aryan&quot;)]<br>let sorted = users.sorted()  // sorted by name because of Comparable<br>let set = Set(users)         // works because of Hashable<br>let isEqual = users[0] == users[1]  // works because of Equatable</pre><p>Conform to these and your type plugs into the entire Swift ecosystem: sorting, sets, dictionaries, diffing, and more.</p><h3>Codable: The Protocol That Replaced Boilerplate</h3><p>Codable is Encodable &amp; Decodable. Conform to it and Swift synthesizes JSON encoding and decoding automatically.</p><pre>struct Article: Codable {<br>    let id: Int<br>    let title: String<br>    let publishedAt: Date<br>    let tags: [String]<br>}<br><br>let json = &quot;&quot;&quot;<br>{<br>    &quot;id&quot;: 1,<br>    &quot;title&quot;: &quot;Swift Protocols&quot;,<br>    &quot;publishedAt&quot;: &quot;2025-08-14T10:00:00Z&quot;,<br>    &quot;tags&quot;: [&quot;swift&quot;, &quot;ios&quot;]<br>}<br>&quot;&quot;&quot;.data(using: .utf8)!<br>let decoder = JSONDecoder()<br>decoder.dateDecodingStrategy = .iso8601<br>let article = try decoder.decode(Article.self, from: json)<br>print(article.title)  // Swift Protocols</pre><p>Three lines to decode a full JSON object into a typed Swift struct. No manual mapping, no stringly-typed dictionary access, no runtime surprises.</p><h3>Protocol-Oriented Programming in Practice</h3><p>The real power shows up in architecture. Here is a testable network layer built entirely on protocols:</p><pre>protocol NetworkService {<br>    func fetch&lt;T: Decodable&gt;(endpoint: String) async throws -&gt; T<br>}<br><br>// Production implementation<br>struct LiveNetworkService: NetworkService {<br>    func fetch&lt;T: Decodable&gt;(endpoint: String) async throws -&gt; T {<br>        let url = URL(string: &quot;https://api.myapp.com&quot; + endpoint)!<br>        let (data, _) = try await URLSession.shared.data(from: url)<br>        return try JSONDecoder().decode(T.self, from: data)<br>    }<br>}<br>// Test implementation - no network required<br>struct MockNetworkService: NetworkService {<br>    var mockData: Data<br>    func fetch&lt;T: Decodable&gt;(endpoint: String) async throws -&gt; T {<br>        try JSONDecoder().decode(T.self, from: mockData)<br>    }<br>}<br>// ViewModel accepts the protocol, not the concrete type<br>class UserViewModel {<br>    private let network: NetworkService<br>    init(network: NetworkService = LiveNetworkService()) {<br>        self.network = network<br>    }<br>}</pre><p>In production: inject LiveNetworkService. In tests: inject MockNetworkService. The view model never knows the difference. This is dependency injection via protocols and it is how testable iOS apps are built.</p><h3>Interview Questions</h3><p><strong>Q: What is a protocol in Swift and how does it differ from inheritance?</strong></p><p>A protocol defines a contract: a set of requirements any conforming type must satisfy. Inheritance copies behavior from a parent class to a child class. Protocols enable composition: a type can conform to many protocols simultaneously, each adding focused capabilities. Unlike inheritance, protocols work with <a href="https://medium.com/@dkvekariya/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659"><strong>structs</strong></a> and <a href="https://medium.com/@dkvekariya/swift-enums-associated-values-raw-values-and-pattern-matching-a5844461beb1"><strong>enums</strong></a>, not just <a href="https://medium.com/@dkvekariya/swift-classes-reference-types-inheritance-and-when-to-use-them-f7a1fd4bd47c"><strong>classes</strong></a>. Swift favors protocols because they are more flexible, more testable, and avoid the fragile base class problems that deep inheritance hierarchies create.</p><p><strong>Q: What is a default implementation in a protocol extension and why is it useful?</strong></p><p>A default implementation is behavior provided in a protocol extension that conforming types automatically inherit without writing any code. It is useful because it lets you add shared behavior to all conforming types at once, allows new protocol requirements to be added without breaking existing conformances, and removes the need for a base class just to share implementation. Conforming types can override the default when they need different behavior.</p><h3>Summary</h3><ul><li>A protocol defines a contract: required properties and methods without implementation.</li><li>Any struct, class, or enum can conform to a protocol.</li><li>Protocol extensions provide default implementations that conforming types inherit for free.</li><li>Protocol composition with &amp; lets functions require multiple capabilities at once.</li><li>Protocols as types enable polymorphism without inheritance.</li><li>Equatable, Comparable, Hashable, and Codable are foundational standard library protocols.</li><li>Protocol-oriented programming powers testable architecture through dependency injection.</li><li>Swift’s standard library, SwiftUI, and Combine are all built on this pattern.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Define a Printable protocol with a prettyPrint() method. Create three types that conform to it: Invoice, Receipt, and ShippingLabel. Add a default implementation that prints the type name, then override it meaningfully for each type.</li><li><strong>Intermediate:</strong> Build a Cacheable protocol with var cacheKey: String { get } and var expiresAfter: TimeInterval { get }. Add a default expiresAfter of 300 seconds via a protocol extension. Conform User, Product, and Article <a href="https://medium.com/@dkvekariya/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659"><strong>structs</strong></a> to it with different cache keys.</li><li><strong>Advanced:</strong> Create a Repository&lt;T&gt; protocol with fetch(id: String) async throws -&gt; T, save(_ item: T) async throws, and delete(id: String) async throws. Build a InMemoryRepository&lt;T&gt; struct that conforms to it using a dictionary. Then create a UserService that depends on any Repository&lt;User&gt; and write a test using the in-memory version without touching a network or database.</li></ol><h3>What’s Next</h3><p><strong>Article 13: Swift Extensions: Adding Behavior Without Subclassing</strong></p><p>Protocols define what a type can do. Extensions define what it already does, retroactively. You can extend any type in Swift, including ones from Apple’s frameworks, and add computed properties, methods, and protocol conformances without touching the original source. It is one of the cleanest features in the language.</p><p><em>Part of </em><strong><em>Swift from Zero to Senior</em></strong><em> — a complete iOS engineering curriculum on Medium.</em></p><p><strong>If protocol-oriented programming clicked today, tap 👏 up to 50 times. It helps this series reach developers still building class hierarchies that should be protocol compositions.</strong></p><p><strong>Follow me</strong> so Article 13 lands in your feed automatically. Extensions are next and they make every type in the language feel like yours.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6b9d48617970" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift Optionals: nil, Unwrapping, and the Safety System Behind the ?]]></title>
            <link>https://dkvekariya.medium.com/swift-optionals-nil-unwrapping-and-the-safety-system-behind-the-24d48687694f?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/24d48687694f</guid>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 04 Sep 2026 14:11:00 GMT</pubDate>
            <atom:updated>2026-09-04T14:11:00.957Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Every </em><em>? in Swift is a compiler-enforced contract. Understand what&#39;s underneath and nil crashes become a thing of the past.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vom6uRNwV21FRzsRqXGy7Q.png" /></figure><h3>Why Optionals Exist</h3><p>In most languages, any variable can be null at any time. You find out at runtime, usually as a crash. Swift takes a different approach: if a value can be absent, you must say so explicitly. The compiler then refuses to let you use it as if it were definitely there.</p><p>That one rule eliminates an entire category of bugs before your app ever runs.</p><h3>What Is an Optional?</h3><p>An optional is a type that wraps another type and adds the possibility of absence.</p><pre>var name: String = &quot;Aryan&quot;   // must have a value<br>var nickname: String? = nil  // may or may not have a value</pre><p>The ? after a type is syntactic sugar for Optional&lt;String&gt;. Under the hood, Optional is just an enum:</p><pre>enum Optional&lt;Wrapped&gt; {<br>    case some(Wrapped)<br>    case none<br>}</pre><p>When you write String?, you get a type that is either .some(&quot;Aryan&quot;) or .none. That&#39;s all an optional is. Everything else follows from this.</p><h3>Forced Unwrapping: The Dangerous Shortcut</h3><p>The ! operator extracts the value from an optional. If the optional is nil, it crashes.</p><pre>var username: String? = &quot;aryan_dev&quot;<br>print(username!)  // &quot;aryan_dev&quot;<br><br>var empty: String? = nil<br>print(empty!)     // 💥 Fatal error: unexpectedly found nil</pre><p>Forced unwrapping has its place. It should never be your default. Every ! in production code is a promise that this value will never be nil here. If that promise breaks, your app crashes.</p><blockquote><strong><em>Rule:</em></strong><em> Treat </em><em>! like a comment that says &quot;I guarantee this is never nil.&quot; If you can&#39;t honestly say that, don&#39;t use it.</em></blockquote><h3>Optional Binding: The Right Way</h3><p>if let safely unwraps an optional. If it has a value, you get it. If not, you take the else branch.</p><pre>var username: String? = &quot;aryan_dev&quot;<br><br>if let name = username {<br>    print(&quot;Hello, \(name)&quot;)  // name is String here, not String?<br>} else {<br>    print(&quot;No username set&quot;)<br>}</pre><p>Swift 5.7 shorthand when the variable name stays the same:</p><pre>if let username {<br>    print(&quot;Hello, \(username)&quot;)<br>}</pre><p>For functions with multiple optional preconditions, <a href="https://dkvekariya.medium.com/swift-conditionals-if-switch-guard-pattern-matching-131e509d4d82"><strong>guard let</strong></a> keeps the code flat:</p><pre>func processOrder(userID: String?, productID: String?, quantity: Int?) {<br>    guard let userID else { return }<br>    guard let productID else { return }<br>    guard let quantity, quantity &gt; 0 else { return }<br> <br>   // All three are safely unwrapped here<br>    placeOrder(user: userID, product: productID, qty: quantity)<br>}</pre><p>This pattern eliminates the pyramid of nested if let blocks that plagues code written by developers still figuring out optionals.</p><h3>Nil Coalescing: Provide a Default</h3><p>The ?? operator returns the unwrapped value if it exists, or a default if it doesn&#39;t.</p><pre>var displayName: String? = nil<br>let name = displayName ?? &quot;Guest&quot;<br>print(name)  // &quot;Guest&quot;</pre><p>Chain it for multiple fallbacks:</p><pre>let name = firstName ?? lastName ?? username ?? &quot;Anonymous&quot;</pre><p>Use this for simple fallback logic. For complex branching, if let or <a href="https://dkvekariya.medium.com/swift-conditionals-if-switch-guard-pattern-matching-131e509d4d82"><strong>guard let</strong></a> is clearer.</p><h3>Optional Chaining: Navigate Safely</h3><p>The ?. operator calls a method or accesses a property on an optional. If the optional is nil, the whole expression returns nil instead of crashing.</p><pre>struct Address {<br>    var city: String<br>}<br><br>struct User {<br>    var address: Address?<br>}<br><br>var user: User? = User(address: Address(city: &quot;Mumbai&quot;))<br>print(user?.address?.city)  // Optional(&quot;Mumbai&quot;)<br>print(user?.address?.city.uppercased())  // Optional(&quot;MUMBAI&quot;)<br>user = nil<br>print(user?.address?.city)  // nil - no crash</pre><p>The result of an optional chain is always optional. If anything in the chain is nil, the whole thing short-circuits to nil.</p><p>Combine with ?? to get a non-optional result:</p><pre>let city = user?.address?.city ?? &quot;Unknown city&quot;</pre><h3>map and flatMap on Optionals</h3><p>Optionals have functional methods too. This surprises most developers.</p><pre>let input: String? = &quot;42&quot;<br><br>// map transforms the wrapped value if it exists<br>let doubled = input.map { Int($0) }<br>// Returns Optional&lt;Optional&lt;Int&gt;&gt; - nested optionals<br>// flatMap flattens the result<br>let number = input.flatMap { Int($0) }<br>// Returns Optional&lt;Int&gt; - cleaner</pre><p>flatMap is especially useful when a transformation itself returns an optional:</p><pre>let userIDString: String? = &quot;123&quot;<br>let userID: Int? = userIDString.flatMap { Int($0) }</pre><p>One line. Safe. No forced unwrapping. This is how functional Swift handles optional transformations.</p><h3>Implicitly Unwrapped Optionals</h3><p>Declared with ! instead of ?. Behave like regular values but crash if nil.</p><pre>var label: UILabel!  // implicitly unwrapped</pre><p>Use this only when a value is guaranteed to be set before first use but cannot be set in init. IBOutlets are the canonical example. UIKit sets them after init but before viewDidLoad, so the guarantee holds.</p><p>Outside of IBOutlets and a handful of UIKit patterns, avoid them. They trade safety for convenience, and the convenience rarely outweighs the risk.</p><h3>Optional in Switch</h3><p>Because optionals are <a href="https://medium.com/@dkvekariya/swift-enums-associated-values-raw-values-and-pattern-matching-a5844461beb1"><strong>enums</strong></a>, you can <a href="https://dkvekariya.medium.com/swift-conditionals-if-switch-guard-pattern-matching-131e509d4d82"><strong>switch</strong></a> on them directly:</p><pre>let score: Int? = 85<br><br>switch score {<br>case .some(let value) where value &gt;= 90:<br>    print(&quot;A&quot;)<br>case .some(let value) where value &gt;= 80:<br>    print(&quot;B&quot;)<br>case .some(let value):<br>    print(&quot;C or below: \(value)&quot;)<br>case .none:<br>    print(&quot;No score recorded&quot;)<br>}</pre><p>Or use the shorthand case let value? syntax:</p><pre>switch score {<br>case let value? where value &gt;= 90:<br>    print(&quot;A: \(value)&quot;)<br>case let value?:<br>    print(&quot;Score: \(value)&quot;)<br>case nil:<br>    print(&quot;No score&quot;)<br>}</pre><h3>Real-World Pattern: Decoding Optional API Fields</h3><pre>struct Product: Decodable {<br>    let id: String<br>    let name: String<br>    let description: String?   // not always returned by API<br>    let discountPrice: Double? // only present during sales<br>    let imageURL: URL?<br>}<br><br>func display(_ product: Product) {<br>    let desc = product.description ?? &quot;No description available&quot;<br>    let price = product.discountPrice.map { &quot;Sale: $\($0)&quot; } ?? &quot;Full price&quot;<br>    let image = product.imageURL ?? URL(string: &quot;https://cdn.myapp.com/placeholder.png&quot;)!<br>    print(desc)<br>    print(price)<br>}</pre><p>Optionals here aren’t just syntax. They’re documentation. Any engineer reading this struct immediately knows which fields the API might omit.</p><h3>Interview Questions</h3><p><strong>Q: What is an optional in Swift and how does it work under the hood?</strong></p><p>An optional is a generic enum with two cases: .some(Wrapped) and .none. The ? syntax is shorthand for Optional&lt;T&gt;. When a variable is declared as String?, the compiler wraps it in this enum. Using the value directly without unwrapping is a compile-time error. This design means nil-related bugs are caught before the app runs, not during user sessions.</p><p><strong>Q: What is the difference between </strong><strong>if let, </strong><a href="https://dkvekariya.medium.com/swift-conditionals-if-switch-guard-pattern-matching-131e509d4d82"><strong>guard let</strong></a><strong>, and </strong><strong>?? for handling optionals?</strong></p><p>if let unwraps an optional inside a block. The unwrapped value is only available inside that block. <a href="https://dkvekariya.medium.com/swift-conditionals-if-switch-guard-pattern-matching-131e509d4d82"><strong>guard let</strong></a> unwraps at the top of a scope and exits if nil. The unwrapped value is available for the rest of the function. ?? provides an inline default value when the optional is nil. Use if let for optional branches, <a href="https://dkvekariya.medium.com/swift-conditionals-if-switch-guard-pattern-matching-131e509d4d82"><strong>guard let</strong></a> for preconditions, and ?? for simple fallback values.</p><h3>Summary</h3><ul><li>An optional is Optional&lt;T&gt;: either .some(value) or .none.</li><li>Forced unwrapping with ! crashes at runtime if the value is nil. Use it only when you can guarantee the value exists.</li><li>if let safely unwraps inside a block. guard let unwraps and exits early if nil.</li><li>?? provides a default value inline when an optional is nil.</li><li>Optional chaining with ?. short-circuits to nil instead of crashing.</li><li>map transforms an optional&#39;s value. flatMap handles transformations that return optionals.</li><li>Implicitly unwrapped optionals (!) are for IBOutlets and UIKit patterns only.</li><li>Optionals are <a href="https://medium.com/@dkvekariya/swift-enums-associated-values-raw-values-and-pattern-matching-a5844461beb1"><strong>enums</strong></a>, so you can use <a href="https://dkvekariya.medium.com/swift-conditionals-if-switch-guard-pattern-matching-131e509d4d82"><strong>switch pattern matching</strong></a> on them directly.</li></ul><h3>Practice</h3><p><strong>Beginner:</strong> Write a function greet(name: String?) -&gt; String that returns &quot;Hello, [name]!&quot; if name exists and &quot;Hello, stranger!&quot; if it doesn&#39;t. Implement it three ways: forced unwrap, if let, and ??. Explain which you&#39;d use in production and why.</p><p><strong>Intermediate:</strong> Given this struct:</p><pre>struct Order {<br>    var user: User?<br>    var shippingAddress: Address?<br>    var promoCode: String?<br>}</pre><p>Write a function summarize(_ order: Order) -&gt; String using optional chaining and ?? to produce a readable summary without any forced unwraps or crashes, regardless of which fields are nil.</p><p><strong>Advanced:</strong> Implement a safeSubscript extension on Array that returns an optional instead of crashing on out-of-bounds access:</p><pre>extension Array {<br>    subscript(safe index: Int) -&gt; Element? { ... }<br>}</pre><p>Then use flatMap to safely extract and transform values from an array of optionals without any force unwraps.</p><h3>What’s Next</h3><p><strong>Article 12: Swift Protocols: Contracts, Conformance, and the Power of Protocol-Oriented Programming</strong></p><p>Optionals showed you how Swift uses the type system to enforce safety. Protocols take that further. They define contracts that any type can fulfill, enabling one of Swift’s most powerful architectural patterns: protocol-oriented programming. It’s the reason Swift code composes so cleanly.</p><p><em>Part of </em><strong><em>Swift from Zero to Senior</em></strong><em> — a complete iOS engineering curriculum on Medium.</em></p><p><strong>If optionals finally make sense as a safety system rather than just syntax, tap 👏 up to 50 times and do 🔁. It helps this series reach developers still scattering </strong><strong>! across their codebase.</strong></p><p><strong>Follow me</strong> so Article 12 lands in your feed automatically. Protocols are next and they will change how you architect everything.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=24d48687694f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift Enums: Associated Values, Raw Values, and Pattern Matching]]></title>
            <link>https://dkvekariya.medium.com/swift-enums-associated-values-raw-values-and-pattern-matching-a5844461beb1?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/a5844461beb1</guid>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 28 Aug 2026 14:01:03 GMT</pubDate>
            <atom:updated>2026-08-28T14:01:03.990Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Most developers use enums like a list of constants. Senior engineers use them to model entire state machines.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_OQUPD9msAXJbM83e2mVGg.png" /></figure><h3>Why Enums Are Bigger Than You Think</h3><p>Every tutorial introduces enums as a fancy list of named values. That framing undersells them completely.</p><p>Swift enums can carry data. They can have methods. They can conform to protocols. They work as the backbone of error handling, network state, navigation routing, and API response modeling. Once you see what they can actually do, you’ll find yourself reaching for them constantly.</p><h3>The Basics</h3><p>An enum defines a type with a fixed set of cases.</p><pre>enum Direction {<br>    case north<br>    case south<br>    case east<br>    case west<br>}<br><br>var heading = Direction.north<br>heading = .west  // Swift infers the type after first assignment</pre><p>The dot syntax after first assignment is a small thing that makes call sites read cleanly.</p><h3>Raw Values</h3><p>Attach a primitive value to each case.</p><pre>enum Planet: Int {<br>    case mercury = 1<br>    case venus<br>    case earth<br>    case mars<br>}<br><br>print(Planet.earth.rawValue)  // 3 - auto-increments from 1<br>// Initialize from a raw value - returns Optional because it can fail<br>let planet = Planet(rawValue: 2)  // Optional&lt;Planet&gt; - venus<br>let unknown = Planet(rawValue: 99)  // nil</pre><p>String raw values are common for API mapping:</p><pre>enum UserRole: String {<br>    case admin = &quot;ADMIN&quot;<br>    case editor = &quot;EDITOR&quot;<br>    case viewer = &quot;VIEWER&quot;<br>}<br><br>// Decode directly from an API response string<br>let role = UserRole(rawValue: &quot;EDITOR&quot;)  // .editor</pre><p>This pattern eliminates strongly-typed comparisons like if role == &quot;ADMIN&quot; scattered across your codebase.</p><h3>Associated Values: The Game Changer</h3><p>Each case can carry its own data. Different cases can carry different types.</p><pre>enum PaymentMethod {<br>    case creditCard(number: String, expiry: String)<br>    case bankTransfer(accountID: String, routingNumber: String)<br>    case applePay<br>    case cash<br>}<br><br>let method = PaymentMethod.creditCard(number: &quot;4111111111111111&quot;, expiry: &quot;12/26&quot;)</pre><p>No struct needed. The data lives inside the case itself.</p><p>Extract the values with pattern matching in a switch:</p><pre>switch method {<br>case .creditCard(let number, let expiry):<br>    print(&quot;Card ending \(number.suffix(4)), expires \(expiry)&quot;)<br>case .bankTransfer(let account, _):<br>    print(&quot;Bank transfer from account \(account)&quot;)<br>case .applePay:<br>    print(&quot;Apple Pay&quot;)<br>case .cash:<br>    print(&quot;Cash payment&quot;)<br>}</pre><p>The compiler forces you to handle every case. Miss one and it won’t build. That exhaustiveness is a feature, not a constraint.</p><h3>Modeling State with Enums</h3><p>This is where enums go from useful to indispensable. Consider a network request that can be in one of several states:</p><pre>enum LoadingState&lt;T&gt; {<br>    case idle<br>    case loading<br>    case loaded(data: T)<br>    case failed(error: Error)<br>}</pre><p>Now your view model holds exactly one value of this type instead of three separate booleans and an optional:</p><pre>// Before — fragile, easy to get into impossible states<br>var isLoading = false<br>var data: [User]?<br>var error: Error?<br><br>// After - only valid states are representable<br>var state: LoadingState&lt;[User]&gt; = .idle</pre><p>A state where isLoading is true AND error is set? Not possible with the enum. This is called <em>making invalid states unrepresentable</em> and it&#39;s one of the most valuable design principles in Swift.</p><h3>Enums with Methods and Computed Properties</h3><p>Enums aren’t just data containers. They can have behavior too.</p><pre>enum Suit: String, CaseIterable {<br>    case hearts = &quot;♥&quot;<br>    case diamonds = &quot;♦&quot;<br>    case clubs = &quot;♣&quot;<br>    case spades = &quot;♠&quot;<br><br>    var isRed: Bool {<br>        self == .hearts || self == .diamonds<br>    }<br><br>    func label() -&gt; String {<br>        &quot;\(rawValue) (\(isRed ? &quot;red&quot; : &quot;black&quot;))&quot;<br>    }<br>}<br><br>print(Suit.hearts.label())     // ♥ (red)<br>print(Suit.allCases.count)     // 4 - CaseIterable gives you this for free</pre><p>CaseIterable synthesizes an allCases array automatically. Useful for populating pickers, iterating every case in tests, or building menus.</p><h3>Indirect Enums: Recursive Structures</h3><p>For tree structures and recursive data, mark the enum indirect:</p><pre>indirect enum TreeNode {<br>    case leaf(value: Int)<br>    case branch(left: TreeNode, right: TreeNode)<br>}<br><br>let tree = TreeNode.branch(<br>    left: .leaf(value: 3),<br>    right: .branch(<br>        left: .leaf(value: 7),<br>        right: .leaf(value: 12)<br>    )<br>)</pre><p>Without indirect, the compiler can&#39;t determine the size of the type at compile time. The keyword tells it to store associated values on the heap instead.</p><h3>Real-World Pattern: API Error Modeling</h3><pre>enum APIError: Error {<br>    case unauthorized<br>    case notFound(resource: String)<br>    case rateLimited(retryAfter: TimeInterval)<br>    case serverError(code: Int, message: String)<br>    case networkUnavailable<br>}<br><br>func handle(_ error: APIError) {<br>    switch error {<br>    case .unauthorized:<br>        redirectToLogin()<br>    case .notFound(let resource):<br>        showAlert(&quot;Could not find \(resource)&quot;)<br>    case .rateLimited(let seconds):<br>        scheduleRetry(after: seconds)<br>    case .serverError(let code, let message):<br>        logError(code: code, message: message)<br>    case .networkUnavailable:<br>        showOfflineBanner()<br>    }<br>}</pre><p>Each error case carries exactly the data it needs. The <a href="https://dkvekariya.medium.com/swift-conditionals-if-switch-guard-pattern-matching-131e509d4d82"><strong>switch</strong></a> handles all of them. No strongly-typed error messages, no integer error codes compared with magic numbers, no optional unwrapping chains.</p><h3>Interview Questions</h3><p><strong>Q: What is the difference between raw values and associated values in Swift enums?</strong></p><p>Raw values are fixed primitive values attached to each case at definition time. Every case of the same enum has the same type. Associated values are dynamic data attached when you create a case. Different cases can carry different types and different amounts of data. Raw values are set in the enum definition; associated values are set at the call site.</p><p><strong>Q: What does “making invalid states unrepresentable” mean?</strong></p><p>It means structuring your types so the compiler physically cannot represent a state that shouldn’t exist in your app. A classic example: replacing isLoading: Bool, data: T?, and error: Error? with a single LoadingState&lt;T&gt; enum. With three separate booleans, you can accidentally set isLoading = true and error = someError simultaneously. With the enum, only one state exists at a time. The compiler enforces it.</p><h3>Summary</h3><ul><li>Enums define a type with a fixed, exhaustive set of cases.</li><li>Raw values attach a primitive to each case at definition time, useful for API mapping.</li><li>Associated values let each case carry its own data, with different types per case.</li><li>Swift’s <a href="https://dkvekariya.medium.com/swift-conditionals-if-switch-guard-pattern-matching-131e509d4d82"><strong>switch</strong></a> is exhaustive on enums: every case must be handled or it won’t compile.</li><li>Enums can have methods, computed properties, and protocol conformances.</li><li>CaseIterable gives you an allCases array for free.</li><li>indirect enables recursive enum structures like trees.</li><li>Modeling state with enums makes invalid states unrepresentable at the type level.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Create a Season enum with four cases. Add a computed property isWarm: Bool and a description: String that returns a short sentence about each season. Iterate all cases using CaseIterable and print the descriptions.</li><li><strong>Intermediate:</strong> Model a Notification enum with cases for message(from: String, text: String), friendRequest(from: String), paymentReceived(amount: Double, currency: String), and systemAlert(title: String). Write a function that takes a Notification and returns the string to display in a push notification banner.</li><li><strong>Advanced:</strong> Build a Result&lt;Success, Failure: Error&gt; type from scratch as a custom enum (don&#39;t use Swift&#39;s built-in). Add a map method that transforms the success value, a mapError method that transforms the failure, and a get() throwing method that returns the success value or throws the error. Then explain why Swift&#39;s standard library already provides this and when you&#39;d use your own instead.</li></ol><h3>What’s Next</h3><p><strong>Article 11: Swift Optionals: nil, Unwrapping, and the Safety System Behind the ?</strong></p><p>Enums taught you how Swift models “this case or that case.” Optionals are built on exactly the same mechanism: a value is either .some(wrapped) or .none. Understanding optionals at that level changes how you read and write Swift forever.</p><p><em>Part of </em><strong><em>Swift from Zero to Senior</em></strong><em> — a complete iOS engineering curriculum on Medium.</em></p><p><strong>If associated values just opened up new ways to model your data, tap 👏 up to 50 times and repost 🔁. It helps this series reach developers who are still using strongly state.</strong></p><p><strong>Follow me</strong> so Article 11 lands in your feed automatically. Optionals are next, and there is a lot more to them than the ? symbol suggests.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a5844461beb1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift Classes: Reference Types, Inheritance, and When to Use Them]]></title>
            <link>https://dkvekariya.medium.com/swift-classes-reference-types-inheritance-and-when-to-use-them-f7a1fd4bd47c?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/f7a1fd4bd47c</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Mon, 24 Aug 2026 11:01:01 GMT</pubDate>
            <atom:updated>2026-08-24T11:01:01.684Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Structs handle most of your data. Classes handle everything that needs to be shared, observed, or torn down.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OpO7LI89IxJW9uhmJ9Kzmg.png" /></figure><h3>Why Classes Still Matter</h3><p>Structs are Swift’s default. But open any UIKit file and you’re in class territory immediately. UIViewController, UIView, URLSession, NotificationCenter all classes. Understanding why these aren&#39;t structs is what makes you a better architect, not just a better syntax writer.</p><h3>What Is a Class in Swift?</h3><p>A class is a <strong>reference type </strong>a blueprint that lives on the heap. When you create an instance, Swift allocates memory for it and hands you a reference (a pointer) to that memory. Every variable that “holds” the class instance actually holds a pointer to the same object.</p><pre>class Vehicle {<br>    var make: String<br>    var speed: Double<br><br>    init(make: String, speed: Double) {<br>        self.make = make<br>        self.speed = speed<br>    }<br><br>    func describe() -&gt; String {<br>        &quot;\(make) going \(speed) km/h&quot;<br>    }<br>}<br><br>let car = Vehicle(make: &quot;Tesla&quot;, speed: 120)<br>print(car.describe())  // Tesla going 120 km/h</pre><p>Unlike structs, classes don’t get a free member wise initializer. You write init yourself.</p><h3>Reference Semantics in Practice</h3><p>This is the single most important thing to understand about classes.</p><pre>var car1 = Vehicle(make: &quot;Tesla&quot;, speed: 100)<br>var car2 = car1       // car2 is NOT a copy — it&#39;s the same object<br><br>car2.speed = 200<br>print(car1.speed)  // 200 - car1 changed too<br>print(car2.speed)  // 200</pre><p>Both car1 and car2 point to the same Vehicle in memory. Changing one changes both. This isn&#39;t a bug it&#39;s the feature. Sometimes you <em>want</em> shared mutable state. A music player&#39;s AudioSession, a user&#39;s AuthManager, a network layer&#39;s URLSessionthese should exist once and be shared everywhere.</p><p>That’s exactly when a class earns its place.</p><h3>Inheritance Extending Behavior Without Rewriting It</h3><p>Classes support inheritance. A subclass gets all the properties and methods of its parent and can override or extend them.</p><pre>class Animal {<br>    var name: String<br><br>    init(name: String) {<br>        self.name = name<br>    }<br><br>    func sound() -&gt; String {<br>        &quot;...&quot;<br>    }<br>}<br><br>class Dog: Animal {<br>    override func sound() -&gt; String {<br>        &quot;Woof&quot;<br>    }<br><br>    func fetch() {<br>        print(&quot;\(name) fetches the ball!&quot;)<br>    }<br>}<br><br>let dog = Dog(name: &quot;Bruno&quot;)<br>print(dog.sound())   // Woof<br>dog.fetch()          // Bruno fetches the ball!</pre><p>The override keyword is required the compiler enforces it. You can&#39;t accidentally override a method. You have to mean it.</p><h3>final Preventing Further Subclassing</h3><pre>final class PaymentProcessor {<br>    // No one can subclass this<br>}</pre><p>Mark a class final when subclassing would break its invariants or when you want the compiler to enable direct method dispatch (faster than dynamic dispatch). Apple marks many of their classes final for exactly this reason.</p><h3>deinit Cleanup When an Object Dies</h3><p>Classes have a deinitializer that runs automatically when the last reference is released.</p><pre>class DatabaseConnection {<br>    let connectionID: String<br><br>    init(id: String) {<br>        self.connectionID = id<br>        print(&quot;Connection \(id) opened&quot;)<br>    }<br><br>    deinit {<br>        print(&quot;Connection \(connectionID) closed&quot;)<br>        // Close socket, release file handles, cancel timers<br>    }<br>}<br><br>var conn: DatabaseConnection? = DatabaseConnection(id: &quot;db_001&quot;)<br>// prints: Connection db_001 opened<br>conn = nil<br>// prints: Connection db_001 closed - deinit fired automatically</pre><p>Structs don’t have deinit. If you need guaranteed cleanup file handles, network sockets, observers, timers you need a class.</p><h3>How ARC Manages Class Memory</h3><p>Swift uses <strong>Automatic Reference Counting</strong> to track how many references point to each class instance. When the count hits zero, deinit runs and the memory is freed.</p><pre>var a: Vehicle? = Vehicle(make: &quot;BMW&quot;,<br>                         speed: 80)  // ref count: 1<br>var b = a                            // ref count: 2<br>a = nil                              // ref count: 1<br>b = nil                              // ref count: 0 → deinit fires</pre><p>This is automatic you don’t call free() or delete. But ARC isn&#39;t free of footguns. Retain cycles (covered in <a href="https://medium.com/@dkvekariya/swift-closures-the-concept-that-unlocks-everything-else-91d441e21f24?sharedUserId=dkvekariya"><strong>Article 7 on closures</strong></a>) can keep the count above zero permanently, leaking the object forever. Classes require more discipline than structs precisely because of this.</p><h3>Class Properties: static vs class</h3><p>Both belong to the type, not an instance. The difference is overridability.</p><pre>class Shape {<br>    static var defaultColor = &quot;black&quot;   // cannot be overridden<br>    class var description: String {     // can be overridden by subclasses<br>        &quot;A generic shape&quot;<br>    }<br>}<br><br>class Circle: Shape {<br>    override class var description: String {<br>        &quot;A circle&quot;<br>    }<br>}<br><br>print(Shape.description)   // A generic shape<br>print(Circle.description)  // A circle</pre><p>Use static when the value should never change per subclass. Use class when subclasses should be able to customize it.</p><h3>Real-World Pattern: Singleton Service</h3><p>The most common class-specific pattern in iOS:</p><pre>final class AnalyticsService {<br>    static let shared = AnalyticsService()<br><br>    private init() {}  // Prevents external instantiation<br><br>    func track(event: String, properties: [String: Any] = [:]) {<br>        // Send to analytics backend<br>        print(&quot;Event: \(event), props: \(properties)&quot;)<br>    }<br>}<br><br>// Usage anywhere in the app<br>AnalyticsService.shared.track(event: &quot;user_login&quot;)</pre><p>One instance, shared across the entire app. This only makes sense as a class a struct would give every call site its own copy, which defeats the purpose entirely.</p><h3>Classes vs Structs: The Real Decision Framework</h3><p>Question Answer → Does this model data? Struct Does multiple code share the same instance? Class Do you need inheritance? Class Do you need deinit for cleanup? Class Should copies be independent? Struct Is this a UIKit component? Class (UIKit requires it) Is this a SwiftUI view? Struct (SwiftUI requires it)</p><p>When in doubt, start with a struct. The compiler will tell you when you actually need a class.</p><h3>Interview Questions</h3><p><strong>Q: What is a class in Swift and how does it differ from a struct?</strong></p><p>A class is a reference type instances live on the heap and multiple variables can share the same object. <a href="https://medium.com/@dkvekariya/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659"><strong>Structs</strong></a> are <a href="https://medium.com/@dkvekariya/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659"><strong>value types</strong></a><strong> </strong>each assignment creates an independent copy. Classes support inheritance and deinit; structs don&#39;t. Classes are managed by ARC and can form retain cycles; structs are stack-allocated (generally) and don&#39;t have this risk.</p><p><strong>Q: When would you choose a class over a struct?</strong></p><p>Choose a class when you need shared mutable state across multiple parts of the app, when you need deinit for resource cleanup, when you&#39;re subclassing (UIKit, for example), or when identity matters two references must point to the exact same instance. Everything else defaults to a struct.</p><h3>Summary</h3><ul><li>Classes are reference types assignment shares the object, not a copy.</li><li>Unlike structs, classes require you to write init manually.</li><li>Subclasses inherit all properties and methods; override is required and enforced.</li><li>final prevents subclassing and enables faster method dispatch.</li><li>deinit runs when ARC drops the reference count to zero use it for resource cleanup.</li><li>static properties can&#39;t be overridden; class properties can.</li><li>Singletons are the canonical class pattern one shared instance for services.</li><li>Default to structs. Reach for classes when you have a specific reason.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Create a BankAccount class with owner: String, balance: Double, and init. Add deposit() and withdraw() methods. Create two variables pointing to the same account and show that a deposit on one is reflected in the other.</li><li><strong>Intermediate:</strong> Build a Logger singleton that stores an in-memory array of log entries (strings). Add log(_ message: String) and clearLogs() methods. Use deinit to print a message showing when the logger would be released then explain why in practice it never fires for a singleton.</li><li><strong>Advanced:</strong> Create a MediaPlayer class with a delegate protocol for playback events. Use a weak delegate reference to avoid a retain cycle. Implement play(), pause(), and stop() and have them notify the delegate. Explain in a comment why the delegate must be weak and what would happen if it weren&#39;t.</li></ol><h3>What’s Next</h3><p><strong>Article 10: Swift Enums — Associated Values, Raw Values, and Pattern Matching</strong></p><p>Enums in Swift are nothing like enums in other languages. They carry data, conform to protocols, have methods, and work as the backbone of Swift’s error handling and state modeling. One of the most powerful features in the entire language and most developers use only 10% of what they can do.</p><p><strong>If the struct vs class decision finally clicked, tap 👏 up to 50 times and do re-post 🔁, it directly helps this series reach developers still confused by reference types.</strong></p><p><strong>Follow me</strong> so Article 10 lands in your feed the moment it’s live. Enums are coming and they’re going to surprise you.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f7a1fd4bd47c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift Structs: Why Apple Chooses Value Types Over Classes]]></title>
            <link>https://dkvekariya.medium.com/swift-structs-why-apple-chooses-value-types-over-classes-f60b79aa3659?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/f60b79aa3659</guid>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 14 Aug 2026 14:01:04 GMT</pubDate>
            <atom:updated>2026-08-14T14:01:04.348Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>The decision that shapes how your entire app manages memory, safety, and state.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vUF6lcGE8twaZcUugCxuQQ.png" /></figure><blockquote><em>What looks like a simple data container is actually Swift’s most powerful tool for writing safe, predictable, performant code.</em></blockquote><h3>Why This Is One of the Most Important Topics in Swift</h3><p>Apple’s own frameworks are built predominantly with structs. SwiftUI.View is a struct. CGRect is a struct. URL is a struct. Array, Dictionary, String all structs.</p><p>This isn’t an accident. It’s a deliberate architectural choice. Understanding why changes how you design every model, every data layer, and every piece of state in your app.</p><h3>What Is a Struct?</h3><p>A struct is a <strong>value type</strong> that groups related data and behavior together.</p><pre>struct User {<br>    let id: String<br>    var name: String<br>    var age: Int<br>}<br><br>let user = User(id: &quot;usr_001&quot;, name: &quot;Aryan&quot;, age: 28)<br>print(user.name)  // Aryan</pre><p>Swift automatically generates a <strong>member-wise initializer</strong> you get init(id:name:age:) for free, no code needed.</p><h3>The Core Idea: Value Semantics</h3><p>This is what makes structs fundamentally different from classes.</p><pre>var original = User(id: &quot;usr_001&quot;, name: &quot;Aryan&quot;, age: 28)<br>var copy = original   // copy gets its own independent copy<br><br>copy.name = &quot;Riya&quot;<br>print(original.name)  // &quot;Aryan&quot; - completely unaffected<br>print(copy.name)      // &quot;Riya&quot;</pre><p>When you assign a struct, you get a <strong>real copy</strong>. Changing one never affects the other. This is called <strong>value semantics</strong> and it eliminates an entire class of bugs.</p><p>Compare this to a class:</p><pre>class UserClass {<br>    var name: String<br>    init(name: String) { self.name = name }<br>}<br><br>var original = UserClass(name: &quot;Aryan&quot;)<br>var copy = original   // both point to the SAME object<br><br>copy.name = &quot;Riya&quot;<br>print(original.name)  // &quot;Riya&quot; - original was changed too</pre><p>With a class, copy is not a copy. It&#39;s another reference to the same object. Shared mutable state is the source of some of the hardest bugs in iOS development.</p><h3>Mutating Methods</h3><p>Struct methods cannot modify properties by default. You must mark them mutating:</p><pre>struct Counter {<br>    var count = 0<br>    mutating func increment() {<br>        count += 1<br>    }<br>    mutating func reset() {<br>        count = 0<br>    }<br>}<br><br>var counter = Counter()<br>counter.increment()<br>counter.increment()<br>print(counter.count)  // 2</pre><p>The mutating keyword is a contract it signals to every reader: <em>&quot;this method changes state.&quot;</em> It also enforces that you cannot call it on a let constant:</p><pre>let fixedCounter = Counter()<br>fixedCounter.increment()  // ❌ Cannot use mutating member on immutable value</pre><p>The compiler catches this at build time. No crash. No runtime surprise.</p><h3>Computed Properties</h3><p>Structs can have properties that compute their value on demand:</p><pre>struct Rectangle {<br>    var width: Double<br>    var height: Double<br>    // Computed - no stored value, calculated each time<br>    var area: Double {<br>        width * height<br>    }<br>    var isSquare: Bool {<br>        width == height<br>    }<br>}<br><br>let rect = Rectangle(width: 10, height: 5)<br>print(rect.area)      // 50.0<br>print(rect.isSquare)  // false</pre><p>Computed properties look like stored properties at the call site clean, no method call syntax needed.</p><h3>Property Observers</h3><p>React to property changes with willSet and didSet:</p><pre>struct StepTracker {<br>    var steps: Int = 0 {<br>        didSet {<br>            if steps &gt; 10_000 {<br>                print(&quot;Goal reached! 🎉&quot;)<br>            }<br>        }<br>    }<br>}<br><br>var tracker = StepTracker()<br>tracker.steps = 10_500  // prints: Goal reached! 🎉</pre><blockquote><strong><em>Production use:</em></strong><em> </em><em>didSet is how you trigger side effects when data changes logging, validation, UI updates in UIKit models.</em></blockquote><h3>Static Properties and Methods</h3><p>Belong to the type itself, not any instance:</p><pre>struct AppConfig {<br>    static let version = &quot;2.1.0&quot;<br>    static let maxRetries = 3<br>    static let baseURL = &quot;https://api.myapp.com&quot;<br>    static func buildURL(endpoint: String) -&gt; String {<br>        baseURL + endpoint<br>    }<br>}<br><br>print(AppConfig.version)                        // &quot;2.1.0&quot;<br>print(AppConfig.buildURL(endpoint: &quot;/users&quot;))   // &quot;https://api.myapp.com/users&quot;</pre><p>No instance needed. Perfect for configuration, constants, and utility functions.</p><h3>Structs vs Classes When to Use Which</h3><p>This comes up in every iOS interview. Here’s the honest answer:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*n9atDELrQvCFThm9_Y8rLg.png" /></figure><p><strong>Use a struct when:</strong></p><ul><li>Modeling data (User, Product, Order, APIResponse)</li><li>The value should be independent when copied</li><li>You don’t need inheritance</li><li>You want thread safety by default</li></ul><p><strong>Use a class when:</strong></p><ul><li>You need a single shared instance (managers, services)</li><li>You need deinit for cleanup</li><li>You’re working with UIKit (which is class-based)</li><li>Identity matters two references must point to the same thing</li></ul><blockquote><em>Apple’s own guideline: </em><strong><em>default to structs.</em></strong><em> Only reach for a class when you have a specific reason.</em></blockquote><h3>Real-World Pattern: API Response Model</h3><pre>struct APIResponse&lt;T: Decodable&gt;: Decodable {<br>    let data: T<br>    let message: String<br>    let statusCode: Int<br>    var isSuccess: Bool {<br>        statusCode &gt;= 200 &amp;&amp; statusCode &lt; 300<br>    }<br>}<br><br>struct Product: Decodable {<br>    let id: String<br>    let name: String<br>    let price: Double<br>    let inStock: Bool<br>}<br><br>// Usage<br>let response: APIResponse&lt;Product&gt; = try JSONDecoder().decode(...)<br>if response.isSuccess {<br>    display(response.data)<br>}</pre><p>Structs + Decodable is the standard pattern for parsing API responses in production iOS apps. Value semantics means your parsed models are safe to pass across layers without unexpected mutation.</p><h3>How Swift Optimizes Struct Memory</h3><p>Swift doesn’t always copy structs immediately. It uses <a href="https://medium.com/@dkvekariya/understanding-copy-on-write-cow-in-swift-0db09995edef"><strong>Copy-on-Write (CoW)</strong></a> for collections the copy only happens when you actually mutate the new value.</p><pre>var array1 = [1, 2, 3, 4, 5]<br>var array2 = array1   // No copy yet — they share the same buffer<br>array2.append(6)      // NOW the copy happens - array1 is unaffected</pre><p>You get value semantics without paying the full copy cost until it’s necessary. This is why passing large arrays around in Swift is cheaper than it looks. (We’ll cover CoW in depth in Phase 3.)</p><h3>Interview Question</h3><p><strong>Q: What’s the difference between a struct and a class in Swift, and when would you choose one over the other?</strong></p><p>Structs are value types assignment creates an independent copy. Classes are reference types assignment creates another reference to the same object. Structs live on the stack (generally), are thread-safe by default, and don’t support inheritance. Classes live on the heap, support inheritance, and share state across references.</p><p>Choose a struct for data models, API responses, and anything where independence on copy is valuable. Choose a class when you need shared state, lifecycle management via deinit, or when interfacing with UIKit. Apple&#39;s official guidance: default to structs, and only use a class when you have a concrete reason.</p><h3>Summary</h3><ul><li>Structs are value types every assignment is an independent copy.</li><li>Classes are reference types assignment shares the same object.</li><li>mutating methods signal and enforce state changes on structs.</li><li>Computed properties calculate values on demand clean call site, no method syntax.</li><li>didSet / willSet react to property changes without subclassing.</li><li>Static properties and methods belong to the type, not any instance.</li><li>Default to structs. Use classes when you specifically need reference semantics.</li><li>Swift uses <a href="https://medium.com/@dkvekariya/understanding-copy-on-write-cow-in-swift-0db09995edef"><strong>Copy-on-Write</strong></a> copies are deferred until mutation occurs.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Create a Temperature struct with a stored property celsius: Double and computed properties fahrenheit and kelvin. Add a mutating func increase(by degrees: Double) method.</li><li><strong>Intermediate:</strong> Model a shopping cart as a struct with an array of CartItem structs. Add mutating methods to add, remove, and clear items, and a computed property for totalPrice. Demonstrate that copying the cart gives you an independent snapshot.</li><li><strong>Advanced:</strong> Create a generic Stack&lt;T&gt; struct with mutating push(), mutating pop(), and a peek computed property. Make it conform to CustomStringConvertible for clean print output. Then explain in a comment why Stack as a struct is safer than Stack as a class in a multi-function codebase.</li></ol><h3>What’s Next</h3><p><strong>Article 9: Swift Classes — Reference Types, Inheritance, deinit, and When They Beat Structs</strong></p><p>You now know structs deeply. Next: classes when shared identity matters, how inheritance works in Swift, what deinit gives you, and why UIKit is entirely class-based. Understanding both sides of this divide makes you a far more intentional architect.</p><p><em>Part of </em><strong><em>Swift from Zero to Senior</em></strong><em> — a complete iOS engineering curriculum on Medium.</em></p><p><strong>If structs finally make sense as a design choice not just syntax tap 👏 up to 50 times and do 🔁. It helps this series reach developers making the same struct vs class mistakes every day.</strong></p><p><strong>Follow me</strong> so Article 9 lands in your feed automatically. Classes build directly on everything you just learned.</p><p>See you in the next one. 🫡</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f60b79aa3659" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>