<?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>Wed, 16 Sep 2026 09:18: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[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>
        <item>
            <title><![CDATA[Swift Closures: The Concept That Unlocks Everything Else]]></title>
            <link>https://dkvekariya.medium.com/swift-closures-the-concept-that-unlocks-everything-else-91d441e21f24?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/91d441e21f24</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[swift-closures]]></category>
            <category><![CDATA[ios-development]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 07 Aug 2026 14:01:04 GMT</pubDate>
            <atom:updated>2026-08-07T14:01:04.009Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Completion handlers, SwiftUI views, map, filter, sort they all run on closures. Understand this and the whole language opens up.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*huHsh6KJnnRjSAeFQLRdAA.png" /></figure><h3>Why Closures Are Non-Negotiable</h3><p>You cannot write real iOS apps without understanding closures. They are the mechanism behind:</p><ul><li>Every completion handler (URLSession, animations, alerts)</li><li>Every SwiftUI body, Button, onTapGesture</li><li>map, filter, sorted, reduce</li><li>DispatchQueue.main.async { }</li><li>async/await under the hood</li><li>Combine publishers and subscribers</li></ul><p>If closures feel fuzzy, everything built on top of them feels like magic. Let’s make them obvious.</p><h3>What Is a Closure?</h3><p>A closure is a function without a name defined inline, where you need it.</p><pre>// Named function<br>func double(_ n: Int) -&gt; Int { n * 2 }<br><br>// Same thing as a closure<br>let double = { (n: Int) -&gt; Int in n * 2 }<br><br>// Use them the same way<br>print(double(5))  // 10</pre><p>The in keyword separates the parameter list and return type from the body. That&#39;s the only structural difference from a function.</p><h3>Syntax Simplification Step by Step</h3><p>Swift lets you strip closure syntax down progressively. Each step is valid:</p><pre>let numbers = [3, 1, 4, 1, 5, 9]<br><br>// 1. Full syntax<br>let sorted = numbers.sorted(by: { (a: Int, b: Int) -&gt; Bool in<br>    return a &lt; b<br>})<br><br>// 2. Type inference - Swift knows the types from context<br>let sorted = numbers.sorted(by: { a, b in<br>    return a &lt; b<br>})<br><br>// 3. Implicit return - single expression closures don&#39;t need `return`<br>let sorted = numbers.sorted(by: { a, b in a &lt; b })<br><br>// 4. Shorthand argument names<br>let sorted = numbers.sorted(by: { $0 &lt; $1 })<br><br>// 5. Trailing closure syntax - when the closure is the last argument<br>let sorted = numbers.sorted { $0 &lt; $1 }<br><br>// 6. Operator function - when an operator matches the signature<br>let sorted = numbers.sorted(by: &lt;)</pre><p>All six produce identical results. Use the level of verbosity that best communicates intent don’t default to the shortest just to look clever.</p><h3>Trailing Closure Syntax</h3><p>When a closure is the last parameter, you can move it outside the parentheses:</p><pre>// Standard<br>UIView.animate(withDuration: 0.3, animations: {<br>    view.alpha = 0<br>})<br><br>// Trailing closure<br>UIView.animate(withDuration: 0.3) {<br>    view.alpha = 0<br>}</pre><p>If the closure is the <em>only</em> parameter, drop the parentheses entirely:</p><pre>DispatchQueue.main.async {<br>    self.tableView.reloadData()<br>}</pre><p>You write this pattern dozens of times a day. Now you know why it looks the way it does.</p><h3>Closures Capture Values</h3><p>This is the critical concept most tutorials rush past.</p><p>A closure <em>captures</em> the variables from its surrounding scope and holds onto them even after that scope ends.</p><pre>func makeCounter() -&gt; () -&gt; Int {<br>    var count = 0<br>    let increment = {<br>        count += 1<br>        return count<br>    }<br>    return increment<br>}<br><br>let counter = makeCounter()<br>print(counter())  // 1<br>print(counter())  // 2<br>print(counter())  // 3</pre><p>makeCounter() has returned but count is still alive because the closure captured it. The closure owns a reference to count and keeps it in memory as long as the closure itself exists.</p><p>This is powerful. It’s also where memory problems begin.</p><h3>Retain Cycles: The Closure Trap</h3><p>When a closure captures self and self holds the closure you have a <strong>retain cycle</strong>. Neither can be deallocated. Memory leaks.</p><pre>class VideoPlayer {<br>    var onComplete: (() -&gt; Void)?<br><br>    func play() {<br>        onComplete = {<br>            self.reset()  // ❌ self captures onComplete, onComplete captures self<br>        }<br>    }<br><br>    func reset() { }<br>}</pre><h4>Fix: Capture lists with [weak self]</h4><pre>func play() {<br>    onComplete = { [weak self] in<br>        self?.reset()  // ✅ weak reference — no cycle<br>    }<br>}</pre><p>[weak self] makes the closure&#39;s reference to self weak it won&#39;t prevent deallocation. Use optional chaining (self?) to safely call methods.</p><h4>[unowned self] the riskier option</h4><pre>onComplete = { [unowned self] in<br>    self.reset()  // No optional chaining needed — but crashes if self is nil<br>}</pre><p>Use [unowned self] only when you are 100% certain self outlives the closure. If you&#39;re not certain, use [weak self]. Always.</p><blockquote><strong><em>Rule:</em></strong><em> Any closure stored as a property that also references </em><em>self needs </em><em>[weak self]. This covers delegates, completion handlers, Combine subscriptions, and timers.</em></blockquote><h3>@escaping Closures</h3><p>By default, closures passed to a function are <strong>non-escaping</strong> they run during the function call and are discarded.</p><p>An <strong>escaping</strong> closure outlives the function it’s stored and called later.</p><pre>class DataService {<br>    var completion: (() -&gt; Void)?  // stored = will outlive the function<br><br>    func load(completion: @escaping () -&gt; Void) {<br>        // Stored for later - must be marked @escaping<br>        self.completion = completion<br>        fetchData()<br>    }<br><br>    func fetchData() {<br>        // ... eventually calls self.completion()<br>    }<br>}</pre><p>Any closure stored in a property, dispatched to another queue, or passed to an async operation must be @escaping. The compiler enforces this if you forget, it tells you.</p><h3>Real-World Pattern: Completion Handler</h3><pre>func fetchUser(id: String, completion: @escaping (Result&lt;User, Error&gt;) -&gt; Void) {<br>    URLSession.shared.dataTask(with: userURL(id: id)) { data, _, error in<br>        if let error = error {<br>            completion(.failure(error))<br>            return<br>        }<br><br>        guard let data = data,<br>              let user = try? JSONDecoder().decode(User.self, from: data) else {<br>            completion(.failure(AppError.invalidData))<br>            return<br>        }<br><br>        DispatchQueue.main.async {<br>            completion(.success(user))<br>        }<br>    }.resume()<br>}<br><br>// Call site<br>fetchUser(id: &quot;usr_123&quot;) { [weak self] result in<br>    switch result {<br>    case .success(let user): self?.updateUI(with: user)<br>    case .failure(let error): self?.showError(error)<br>    }<br>}</pre><p>This is the pattern that powered iOS apps for years before async/await. You will still encounter it in legacy codebases. Understanding it deeply matters.</p><h3>Interview Question</h3><p><strong>Q: What is a retain cycle in a closure and how do you fix it?</strong></p><p>A retain cycle occurs when a closure captures self strongly and self holds a strong reference to the closure. Neither object&#39;s reference count reaches zero, so both leak memory permanently. The fix is a <strong>capture list</strong>: [weak self] makes the closure hold a weak reference to self, breaking the cycle. Use optional chaining (self?.method()) to safely call methods. Use [unowned self] only when you can guarantee self outlives the closure otherwise [weak self] is always the safer choice.</p><h3>Summary</h3><ul><li>A closure is an anonymous function defined inline.</li><li>Syntax can be simplified progressively use the level that communicates intent best.</li><li>Trailing closure syntax moves the last closure argument outside the parentheses.</li><li>Closures <strong>capture</strong> variables from their surrounding scope and keep them alive.</li><li>Retain cycles happen when a closure captures self and self owns the closure.</li><li>Break retain cycles with [weak self] use [unowned self] only when certain.</li><li>@escaping marks closures that outlive the function they&#39;re passed to.</li><li>Any closure stored as a property or dispatched asynchronously must be @escaping.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Use map, filter, and sorted with trailing closure syntax on this array: [5, 3, 8, 1, 9, 2, 7]. Filter out numbers below 5, double the remaining ones, then sort descending.</li><li><strong>Intermediate:</strong> Write a debounce function that takes a closure and a delay, and only executes the closure if it hasn&#39;t been called again within the delay window. Use DispatchWorkItem and [weak self] correctly.</li><li><strong>Advanced:</strong> Create a Cache&lt;Key: Hashable, Value&gt; class with a fetch method that takes a key and an @escaping completion handler. If the value exists in the cache, call completion immediately. Otherwise, simulate an async load, store the result, and call completion without leaking memory.</li></ol><h3>What’s Next</h3><p><strong>Article 8: Swift Structs — Value Types, Mutability, and Why Swift Prefers Them Over Classes</strong></p><p>Closures taught you how to pass behavior around. Structs teach you how to model data safely. They’re the backbone of Swift’s value semantics and understanding why Swift defaults to structs over classes is one of the most important architectural decisions you’ll ever make.</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 capture lists finally made sense today, tap 👏 up to 50 times and do Repost 🔁 it helps this series reach developers who are stuck on the same concept.</strong></p><p><strong>Follow me</strong> so Article 8 lands in your feed automatically. Structs build directly on what you learned here.</p><p>See you in the next one.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=91d441e21f24" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Background App Refresh in iOS: Implementation, Debugging & Pitfalls (Part 2 of 2)]]></title>
            <link>https://dkvekariya.medium.com/background-app-refresh-in-ios-implementation-debugging-pitfalls-part-2-of-2-01ed202f0824?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/01ed202f0824</guid>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Thu, 30 Jul 2026 14:11:01 GMT</pubDate>
            <atom:updated>2026-07-30T14:11:01.445Z</atom:updated>
            <content:encoded><![CDATA[<h4>Real code, a hidden debugging trick, and the mistakes that quietly hurt your app.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pbzSejapXfgcuIWcYDPVWQ.png" /></figure><p>In <a href="https://claude.ai/chat/ba67f90f-9d17-4ac1-8286-6226906022c7#">Part 1</a>, we covered what Background App Refresh actually is, why iOS gates it so tightly, and how the scheduling decision gets made. Now let’s get practical: real code, how to test something the OS deliberately makes hard to test, and the mistakes that quietly tank your app’s scheduling priority.</p><h3>Step 1: Registering the task</h3><p>Register every task identifier <strong>before</strong> application(_:didFinishLaunchingWithOptions:) returns (or in your App init if using SwiftUI&#39;s App protocol). Registering late even by one async tick can cause silent failures.</p><pre>import BackgroundTasks<br><br>func application(_ application: UIApplication,<br>                  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -&gt; Bool {<br>    BGTaskScheduler.shared.register(<br>        forTaskWithIdentifier: &quot;com.yourapp.refresh&quot;,<br>        using: nil<br>    ) { task in<br>        self.handleAppRefresh(task: task as! BGAppRefreshTask)<br>    }<br>    return true<br>}</pre><h3>Step 2: Scheduling a request</h3><pre>func scheduleAppRefresh() {<br>    let request = BGAppRefreshTaskRequest(identifier: &quot;com.yourapp.refresh&quot;)<br>    request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60) // hint only<br>    do {<br>        try BGTaskScheduler.shared.submit(request)<br>    } catch {<br>        print(&quot;Could not schedule app refresh: \(error)&quot;)<br>    }<br>}</pre><p>Call this from applicationDidEnterBackground and again at the end of every successful task run each request is single-use.</p><h3>Step 3: Handling the task</h3><pre>func handleAppRefresh(task: BGAppRefreshTask) {<br>    scheduleAppRefresh() // queue the next one immediately<br>    <br>    let operation = RefreshDataOperation()<br><br>    task.expirationHandler = {<br>        operation.cancel()<br>    }<br><br>    operation.completionBlock = {<br>        task.setTaskCompleted(success: !operation.isCancelled)<br>    }<br><br>    OperationQueue().addOperation(operation)<br>}</pre><p>The expirationHandler is not optional in practice if the OS revokes your time and you don&#39;t respond, you get penalized, not just interrupted.</p><h3>Debugging: forcing a run without waiting days</h3><p>Apple provides a real debugger command for this most developers never discover it:</p><pre>e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@&quot;com.yourapp.refresh&quot;]</pre><p>Set a breakpoint after your app enters the background (or right after registration), paste that into the LLDB console, and iOS fires your handler immediately as if the OS had decided to schedule it. There’s also an expiration-simulation variant using _simulateExpirationForTaskWithIdentifier: to test your cancellation logic without waiting for the real timeout.</p><h3>What to avoid</h3><ul><li><strong>Don’t treat </strong><strong>earliestBeginDate as a schedule.</strong> It&#39;s a floor, not a target. Requesting &quot;15 minutes from now&quot; does not mean it runs at minute 15.</li><li><strong>Don’t do heavy work in a </strong><strong>BGAppRefreshTask.</strong> It&#39;s capped around 30 seconds. Move large downloads or processing to BGProcessingTask, which supports longer windows and can require external power/network conditions you specify (requiresNetworkConnectivity, requiresExternalPower).</li><li><strong>Don’t forget to reschedule.</strong> Every task request is consumed on execution. If you don’t call scheduleAppRefresh() again inside the handler, your app effectively opts itself out of future background runs.</li><li><strong>Don’t ignore the expiration handler.</strong> Letting the system kill your task ungracefully damages your app’s scheduling reputation with iOS’s prediction model future requests get deprioritized.</li><li><strong>Don’t rely on background refresh for anything time-critical.</strong> Push notifications with content-available: 1 (silent push) are a more reliable trigger for urgent background work, though they&#39;re similarly budget-limited and not guaranteed either.</li><li><strong>Don’t test only in the simulator.</strong> The simulator’s background execution behavior is dramatically more permissive than real hardware. Code that “just works” in Xcode’s simulator frequently never fires on a real device under real battery/usage conditions.</li><li><strong>Don’t assume Low Power Mode users will ever see it run.</strong> Background refresh scheduling is effectively disabled under Low Power Mode plan a graceful degraded experience (e.g., pull-to-refresh) instead of depending on it.</li></ul><h3>The mental model to keep</h3><p>Background App Refresh isn’t a feature you <em>turn on</em> it’s a request you <em>earn</em>, repeatedly, based on how the OS models your app’s relevance to the user. Design for “this might not run for a while,” build a solid foreground refresh path as the real source of truth, and treat background execution as a bonus that keeps content warm never as your app’s only path to fresh data.</p><p>Get that mental model right, and every “why isn’t this working” debugging session gets a lot shorter.</p><p>If BGTaskScheduler finally clicked for you today, tap 👏 up to 50 times it directly helps this series reach more iOS developers.</p><p>Follow me so the next deep dive lands in your feed the moment it’s live. This is the pattern behind almost every “why isn’t my background task running” bug report you’ll ever get.</p><p>Repost it if you think it’ll save your audience a debugging session. 🔁</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=01ed202f0824" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Background App Refresh in iOS: Busting the Myths (Part 1 of 2)]]></title>
            <link>https://dkvekariya.medium.com/background-app-refresh-in-ios-busting-the-myths-part-1-of-2-0bd58ab3bcca?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/0bd58ab3bcca</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[ios-development]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Fri, 24 Jul 2026 14:16:01 GMT</pubDate>
            <atom:updated>2026-08-02T04:31:39.434Z</atom:updated>
            <content:encoded><![CDATA[<h4>What it really is, why iOS gates it so tightly, and how the scheduling decision gets made.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*F6_5hioIq87Mtq50BEk75g.png" /></figure><p>If you’ve ever asked “why isn’t my app refreshing in the background even though I enabled the capability,” you’re not alone. Background App Refresh is one of the most misunderstood mechanisms in iOS. Developers treat it like a cron job. It is not. It’s a negotiation and iOS almost always wins.</p><p>This two-part series breaks down what Background Refresh actually is, why Apple built it this way, how it works under the hood, and in <a href="https://medium.com/@dkvekariya/background-app-refresh-in-ios-implementation-debugging-pitfalls-part-2-of-2-01ed202f0824"><strong>Part 2</strong></a><strong> </strong>exactly how to implement it correctly, with the mistakes to avoid.</p><h3>Myth 1: Enabling the capability guarantees my code runs</h3><p>No. Toggling <strong>Background App Refresh</strong> in your target’s Signing &amp; Capabilities tab, or the switch in Settings, only makes background execution <em>possible</em>. It does not schedule anything. It does not promise a time. It does not even promise it’ll happen today.</p><p>Think of it as asking permission to be considered, not booking a slot.</p><h3>Myth 2: Background Refresh means my app runs continuously in the background</h3><p>Also no. iOS is not multitasking your app the way macOS multitasks a desktop app. Your app gets a short, budgeted burst of CPU time typically <strong>30 seconds or less</strong> to do something useful (fetch data, update a cache, prep content) before iOS suspends it again.</p><h3>What Background App Refresh actually is</h3><p>Background App Refresh (and its modern replacement, the <strong>BGTaskScheduler</strong> framework introduced in iOS 13) is a system-mediated scheduling API that lets your app request a short window of execution time in the background, so that when the user <em>does</em> open the app, content feels fresh instead of stale.</p><p>There are two flavors under the modern API:</p><ul><li><strong>BGAppRefreshTask</strong> short, lightweight refreshes (think: pulling new feed items).</li><li><strong>BGProcessingTask</strong> longer, heavier work (think: database cleanup, ML model updates, large downloads) that can run for minutes and can require the device to be charging/on Wi-Fi.</li></ul><p>The old application(_:performFetchWithCompletionHandler:) (Background Fetch) still technically works but is deprecated in spirit Apple wants everyone on BGTaskScheduler now.</p><h3>Why Apple built it this way</h3><p>Battery life and thermal budget are finite, shared resources across every app on the device. If every app got to run whenever it wanted, your battery would be gone by lunch. So Apple centralized the decision-making into the OS itself, which uses on-device machine learning to predict:</p><ul><li>Which apps you’re likely to open soon</li><li>What time of day you typically use them</li><li>Your charging habits and Wi-Fi availability</li><li>Overall system battery and thermal state</li></ul><p>Your app doesn’t decide when it runs. <strong>iOS decides</strong>, based on your usage patterns, and only <em>executes</em> the task you scheduled if conditions look favorable.</p><h3>How it actually works, step by step</h3><ol><li><strong>You register a task identifier</strong> at app launch, before applicationDidFinishLaunching returns, using BGTaskScheduler.shared.register(forTaskWithIdentifier:using:launchHandler:).</li><li><strong>You submit a request</strong> (BGAppRefreshTaskRequest or BGProcessingTaskRequest) with an earliestBeginDate a hint, not a promise.</li><li><strong>iOS logs the request</strong> and quietly evaluates it against its behavioral model. It considers your app’s engagement score, battery level, network state, and device idle time.</li><li><strong>When the OS decides the moment is right</strong>, it wakes your app briefly and calls your registered launch handler.</li><li><strong>You have a strict time budget.</strong> You must call task.setTaskCompleted(success:) before the system-imposed limit, or iOS kills your process and this part matters <strong>penalizes your app&#39;s future scheduling priority</strong> for not finishing on time.</li><li><strong>You should always schedule the next request</strong> before you finish the current one, because these are one-shot, not recurring.</li></ol><h3>Where it lives in your project</h3><ul><li><strong>Info.plist</strong>: UIBackgroundModes array needs fetch (legacy) and/or processing entries, plus BGTaskSchedulerPermittedIdentifiers listing every task identifier string you&#39;ll use.</li><li><strong>Signing &amp; Capabilities</strong>: “Background Modes” capability, with “Background fetch” and/or “Background processing” checked.</li><li><strong>AppDelegate / App struct</strong>: registration must happen synchronously and early a common source of silent failures if it’s buried inside an async closure.</li></ul><h3>When does it actually run?</h3><p>This is the honest, unglamorous answer: <strong>whenever iOS wants to.</strong> There’s no fixed interval. In practice:</p><ul><li>Apps used frequently and recently get more generous scheduling.</li><li>Apps rarely opened may go days without a background execution.</li><li>Low Power Mode disables background refresh scheduling almost entirely.</li><li>The simulator and real devices behave <em>very</em> differently the simulator is far more permissive, which is exactly why so many developers ship code that “worked on my machine” and fails silently in production.</li></ul><p>That unpredictability is the root of almost every myth in this space, and it’s exactly what we’ll deal with head-on in <a href="https://medium.com/@dkvekariya/background-app-refresh-in-ios-implementation-debugging-pitfalls-part-2-of-2-01ed202f0824">Part 2</a> along with the implementation code, debugging tricks (yes, there’s a legitimate way to force-trigger it for testing), and the mistakes that get apps throttled by the OS without the developer ever finding out why.</p><p>If Background App Refresh finally makes sense today, tap 👏 up to 50 times it directly helps this series reach more iOS developers.</p><p>Follow me so <a href="https://medium.com/@dkvekariya/background-app-refresh-in-ios-implementation-debugging-pitfalls-part-2-of-2-01ed202f0824"><strong>Part 2: Implementation, Debugging &amp; Pitfalls</strong></a> lands in your feed the moment it’s live. Everything in this article is the foundation for the code we write next.</p><p>Repost it if you think it’ll help someone on your team stop fighting the scheduler. 🔁</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0bd58ab3bcca" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift Functions: Everything a Senior iOS Engineer Knows That You Don’t]]></title>
            <link>https://dkvekariya.medium.com/swift-functions-everything-a-senior-ios-engineer-knows-that-you-dont-924f559b5fbd?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/924f559b5fbd</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[function]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Thu, 16 Jul 2026 14:01:03 GMT</pubDate>
            <atom:updated>2026-07-16T14:01:03.382Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Functions are the building blocks of every app. Most developers use 20% of what Swift functions can do.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wGnJsiT5yZgMjMzxVjFpGQ.png" /></figure><h3>Why Functions Deserve a Deep Dive</h3><p>Every iOS app is a collection of functions calling other functions. Get them wrong and you end up with bloated view controllers, untestable logic, and APIs that are painful to use. Get them right and your code reads like well-written prose.</p><p>Swift’s function system is one of the richest in any language. Most developers only scratch the surface.</p><h3>The Basics</h3><pre>func greet(name: String) -&gt; String {<br>    return &quot;Hello, \(name)!&quot;<br>}<br><br>let message = greet(name: &quot;Aryan&quot;)<br>print(message)  // Hello, Aryan!</pre><p>Three parts: name, parameters, return type. But Swift adds layers on top of each one.</p><h3>Argument Labels vs Parameter Names</h3><p>This is one of Swift’s most distinctive features and one of its best.</p><pre>func move(from start: String, to destination: String) {<br>    print(&quot;Moving from \(start) to \(destination)&quot;)<br>}</pre><pre>move(from: &quot;London&quot;, to: &quot;Dubai&quot;)</pre><ul><li>from and to are <strong>argument labels</strong> what the caller sees</li><li>start and destination are <strong>parameter names </strong>what the function body uses</li></ul><p>This lets your function calls read like English sentences. It’s why Apple’s APIs feel so natural.</p><h3>Omitting the label with _</h3><pre>func square(_ number: Int) -&gt; Int {<br>    return number * number<br>}<br><br>square(5)  // ✅ No label needed - reads cleanly</pre><p>Use _ when the parameter&#39;s purpose is obvious from context. Overuse it and you lose clarity.</p><h3>Default Parameters</h3><pre>func fetchUsers(page: Int = 1, limit: Int = 20) -&gt; [User] {<br>    // fetch logic<br>}<br><br>fetchUsers()              // page: 1, limit: 20<br>fetchUsers(page: 2)       // page: 2, limit: 20<br>fetchUsers(page: 3, limit: 50)</pre><p>Default parameters reduce the number of overloads you need to write. Put defaults at the end of the parameter list — it’s a Swift convention and makes call sites cleaner.</p><h3>Multiple Return Values with Tuples</h3><pre>func minMax(of array: [Int]) -&gt; (min: Int, max: Int) {<br>    return (array.min()!, array.max()!)<br>}<br><br>let result = minMax(of: [3, 1, 7, 2, 9])<br>print(result.min)  // 1<br>print(result.max)  // 9</pre><p>Named tuple elements make the return value self-documenting. No need to create a whole struct for simple paired returns.</p><h3>Variadic Parameters</h3><p>Accept any number of arguments of the same type:</p><pre>func average(_ numbers: Double...) -&gt; Double {<br>    guard !numbers.isEmpty else { return 0 }<br>    return numbers.reduce(0, +) / Double(numbers.count)<br>}<br><br>average(80, 90, 95)        // 88.33<br>average(100, 75, 60, 85)   // 80.0</pre><p>Inside the function, numbers is a [Double]. Variadic parameters must come last if mixed with others.</p><h3>inout Parameters Mutating Outside the Function</h3><p>By default, function parameters are constants. inout lets a function modify the caller&#39;s variable directly.</p><pre>func double(_ value: inout Int) {<br>    value *= 2<br>}<br><br>var score = 10<br>double(&amp;score)<br>print(score)  // 20</pre><p>The &amp; at the call site signals mutation a deliberate design choice by Swift to make side effects visible.</p><blockquote><strong><em>When to use:</em></strong><em> Low-level algorithms, swap operations, performance-critical paths where you want to avoid copying. In most app code, prefer returning a new value instead of mutating in place.</em></blockquote><h3>@discardableResult</h3><p>By default, Swift warns you if you ignore a function’s return value. Sometimes that’s intentional:</p><pre>@discardableResult<br>func saveToCache(_ data: Data) -&gt; Bool {<br>    // save logic<br>    return true<br>}<br><br>saveToCache(data)         // ✅ No warning - return value ignored intentionally<br>let success = saveToCache(data)  // ✅ Also fine</pre><p>Use sparingly. If the return value is always important, don’t suppress the warning.</p><h3>Functions as First-Class Citizens</h3><p>In Swift, functions are values. You can assign them to variables, pass them as arguments, and return them from other functions.</p><pre>// Assign a function to a variable<br>func add(_ a: Int, _ b: Int) -&gt; Int { a + b }<br>func multiply(_ a: Int, _ b: Int) -&gt; Int { a * b }<br><br>var operation: (Int, Int) -&gt; Int = add<br>print(operation(3, 4))   // 7<br>operation = multiply<br>print(operation(3, 4))   // 12</pre><h4>Passing functions as parameters</h4><pre>func applyOperation(_ a: Int, _ b: Int, using op: (Int, Int) -&gt; Int) -&gt; Int {<br>    op(a, b)<br>}<br><br>applyOperation(5, 3, using: add)       // 8<br>applyOperation(5, 3, using: multiply)  // 15</pre><p>This is the foundation of functional programming in Swift and directly how map, filter, and sort work under the hood.</p><h3>Nested Functions</h3><p>Functions can live inside other functions scoped to where they’re needed:</p><pre>func processPayment(amount: Double) -&gt; String {<br>    func formatCurrency(_ value: Double) -&gt; String {<br>        String(format: &quot;$%.2f&quot;, value)<br>    }<br><br>    let tax = amount * 0.18<br>    let total = amount + tax<br>    return &quot;Total: \(formatCurrency(total))&quot;<br>}</pre><p>The inner formatCurrency is invisible outside processPayment. Use nested functions to keep helpers private and co-located with their only user.</p><h3>Real-World Pattern: Configurable Network Request</h3><pre>func request(<br>    endpoint: String,<br>    method: HTTPMethod = .get,<br>    body: Data? = nil,<br>    retries: Int = 3,<br>    completion: (Result&lt;Data, Error&gt;) -&gt; Void<br>) {<br>    // network logic<br>}<br><br>// Clean, readable call sites<br>request(endpoint: &quot;/users&quot;) { result in<br>    // handle result<br>}<br>request(endpoint: &quot;/orders&quot;, method: .post, body: orderData) { result in<br>    // handle result<br>}</pre><p>Default parameters + labeled arguments = an API that reads clearly at every call site and requires minimal boilerplate for common cases.</p><h3>Interview Question</h3><p><strong>Q: What’s the difference between a parameter name and an argument label in Swift?</strong></p><p>The <strong>argument label</strong> is used at the call site it’s what the caller writes. The <strong>parameter name</strong> is used inside the function body. By default they’re the same. You can specify different ones with func move(from start: String) where from is the label and start is the internal name. Use _ to omit the label entirely. This design lets Swift APIs read like natural language while keeping internal naming clean and descriptive.</p><h3>Summary</h3><ul><li>Argument labels make call sites read like English use them deliberately.</li><li>_ omits the label when context makes the parameter obvious.</li><li>Default parameters reduce overloads and simplify call sites.</li><li>Tuples return multiple values without a full struct.</li><li>inout mutates the caller&#39;s variable always visible with &amp; at the call site.</li><li>@discardableResult suppresses the unused return value warning use sparingly.</li><li>Functions are first-class values assignable, passable, returnable.</li><li>Nested functions scope helpers to exactly where they’re needed.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Write a function bmi(weight: Double, height: Double) -&gt; String that computes BMI and returns &quot;Underweight&quot;, &quot;Normal&quot;, &quot;Overweight&quot;, or &quot;Obese&quot;. Use labeled parameters and a default unit of kilograms/meters.</li><li><strong>Intermediate:</strong> Write a retry function that takes a throwing operation as a parameter and a retry count (default 3), attempts the operation up to that many times, and returns the result or throws the last error.</li><li><strong>Advanced:</strong> Implement a pipeline function that takes a value and an array of transformation functions [(T) -&gt; T], applies them in order, and returns the final result. Make it generic so it works with any type.</li></ol><h3>What’s Next</h3><p><strong>Article 7: Swift Closures Syntax, Capture Lists, Memory, and Why They’re Everywhere</strong></p><p>You just learned that functions are first-class values. Closures are the natural evolution of that idea anonymous functions you define inline. They power map, filter, sort, completion handlers, SwiftUI&#39;s body, and almost every async API. This one is a big deal.</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 functions finally clicked for you today, tap 👏 up to 50 times it directly helps this series reach more iOS developers.</strong></p><p><strong>Follow me</strong> so Article 7 lands in your feed the moment it’s live. Closures build directly on everything in this article.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=924f559b5fbd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Swift Loops: for-in, while, repeat-while, and What Senior Engineers Actually Use]]></title>
            <link>https://dkvekariya.medium.com/swift-loops-for-in-while-repeat-while-and-what-senior-engineers-actually-use-750d27904ba9?source=rss-6317b0b805bf------2</link>
            <guid isPermaLink="false">https://medium.com/p/750d27904ba9</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[loop]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Divyesh Vekariya]]></dc:creator>
            <pubDate>Sat, 04 Jul 2026 14:01:02 GMT</pubDate>
            <atom:updated>2026-07-04T14:01:02.167Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Loops are everywhere in your app. Writing them wrong costs performance. Writing them right is an art.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tAGx2jLg4DHsKXh0RE0ELw.png" /></figure><h3>Why Loops Matter More Than You Think</h3><p>Loops touch nearly every layer of an iOS app rendering lists, processing data, animating frames, parsing responses. A poorly written loop in a hot path can tank your frame rate or freeze the main thread. A well-written one is invisible.</p><p>Swift gives you several looping tools. Knowing which one to reach for and why separates junior code from production-grade code.</p><h3>for-in: Your Most-Used Loop</h3><pre>let fruits = [&quot;apple&quot;, &quot;banana&quot;, &quot;cherry&quot;]<br><br>for fruit in fruits {<br>    print(fruit)<br>}<br>// apple<br>// banana<br>// cherry</pre><p>Works on any Sequence arrays, sets, dictionaries, ranges, strings.</p><pre>// Range loop<br>for i in 1...5 {<br>    print(i)  // 1 2 3 4 5<br>}<br><br>// String characters<br>for char in &quot;Swift&quot; {<br>    print(char)  // S w i f t<br>}<br><br>// Dictionary - order not guaranteed<br>let scores = [&quot;Alice&quot;: 95, &quot;Bob&quot;: 87]<br>for (name, score) in scores {<br>    print(&quot;\(name): \(score)&quot;)<br>}</pre><h4>When you don’t need the index</h4><pre>// ❌ Unnecessary index<br>for i in 0..&lt;fruits.count {<br>    print(fruits[i])<br>}</pre><pre>// ✅ Direct iteration<br>for fruit in fruits {<br>    print(fruit)<br>}</pre><p>Only use index-based loops when you actually need the index.</p><h3>enumerated(): Index + Value Together</h3><pre>let players = [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Charlie&quot;]<br><br>for (index, player) in players.enumerated() {<br>    print(&quot;\(index + 1). \(player)&quot;)<br>}<br>// 1. Alice<br>// 2. Bob<br>// 3. Charlie</pre><blockquote><strong><em>Production use:</em></strong><em> Perfect for numbered lists, position-dependent logic, and debugging output. Cleaner than managing a counter variable manually.</em></blockquote><h3>zip(): Loop Two Collections Together</h3><pre>let names = [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Charlie&quot;]<br>let scores = [95, 87, 92]<br><br>for (name, score) in zip(names, scores) {<br>    print(&quot;\(name) scored \(score)&quot;)<br>}<br>// Alice scored 95<br>// Bob scored 87<br>// Charlie scored 92</pre><p>zip stops at the shorter collection no index out of bounds risk. Use it whenever you&#39;re pairing two arrays.</p><h3>stride: Precise Step Control</h3><p>When you need a loop that doesn’t increment by 1:</p><pre>// Count up by 2<br>for i in stride(from: 0, to: 10, by: 2) {<br>    print(i)  // 0 2 4 6 8<br>}<br><br>// Count down<br>for i in stride(from: 10, through: 0, by: -2) {<br>    print(i)  // 10 8 6 4 2 0<br>}</pre><ul><li>stride(from:to:by:) excludes the end value</li><li>stride(from:through:by:) includes the end value</li></ul><blockquote><strong><em>Real-world use:</em></strong><em> Animation frame stepping, audio sample processing, pagination with custom step sizes.</em></blockquote><h3>while: Loop Until a Condition Fails</h3><p>Use while when you don&#39;t know how many iterations you need upfront.</p><pre>var attempts = 0<br>var success = false<br><br>while !success &amp;&amp; attempts &lt; 3 {<br>    success = tryNetworkRequest()<br>    attempts += 1<br>}</pre><p>The condition is checked <strong>before</strong> each iteration. If it’s false from the start, the body never runs.</p><h3>repeat-while: Always Runs At Least Once</h3><pre>var pin = &quot;&quot;<br><br>repeat {<br>    pin = promptUserForPIN()<br>} while pin.count != 4</pre><p>The body runs <strong>first</strong>, then the condition is checked. Use this when the action must happen at least once before you can evaluate the condition like prompting for input.</p><h3>break and continue: Controlling Flow</h3><pre>// break — exit the loop entirely<br>for i in 1...10 {<br>    if i == 5 { break }<br>    print(i)  // 1 2 3 4<br>}</pre><pre>// continue - skip this iteration, keep going<br>for i in 1...10 {<br>    if i % 2 == 0 { continue }<br>    print(i)  // 1 3 5 7 9<br>}</pre><h4>Labeled statements for nested loops</h4><pre>outer: for row in 0..&lt;3 {<br>    for col in 0..&lt;3 {<br>        if row == 1 &amp;&amp; col == 1 {<br>            break outer  // exits BOTH loops<br>        }<br>        print(&quot;(\(row), \(col))&quot;)<br>    }<br>}</pre><p>Without the label, break only exits the inner loop. Labels give you precise control over nested loop exits use them when the intent is clear.</p><h3>Performance: What Actually Matters</h3><h4>Avoid repeated property access in loop conditions</h4><pre>let items = largeArray<br>// ❌ .count is evaluated every iteration<br>for i in 0..&lt;items.count { ... }<br><br>// ✅ Captured once - compiler usually optimizes this, but being explicit is better<br>let count = items.count<br>for i in 0..&lt;count { ... }</pre><h4>Prefer forEach for functional style but know the tradeoff</h4><pre>fruits.forEach { fruit in<br>    print(fruit)<br>}</pre><p>forEach is clean for side effects but has one critical difference from for-in: <strong>you cannot use </strong><strong>break or </strong><strong>continue inside </strong><strong>forEach</strong>. It&#39;s a closure return just exits the closure, not the loop.</p><pre>// ❌ This doesn&#39;t break the loop — it just returns from the closure<br>fruits.forEach { fruit in<br>    if fruit == &quot;banana&quot; { return }  // skips &quot;banana&quot;, continues to &quot;cherry&quot;<br>    print(fruit)<br>}</pre><pre>// ✅ Use for-in if you need break/continue<br>for fruit in fruits {<br>    if fruit == &quot;banana&quot; { break }  // actually stops the loop<br>    print(fruit)<br>}</pre><p>This catches a lot of developers off guard. Know the difference.</p><h3>Real-World Pattern: Pagination</h3><pre>func fetchAllPages(startPage: Int = 1, maxPages: Int = 10) async throws -&gt; [Item] {<br>    var results: [Item] = []<br>    var currentPage = startPage<br><br>    while currentPage &lt;= maxPages {<br>        let page = try await api.fetch(page: currentPage)<br>        results.append(contentsOf: page.items)<br>        guard page.hasNextPage else { break }<br>        currentPage += 1<br>    }<br>    return results<br>}</pre><p>while with a break on condition clean, readable, safe. This is production pagination logic.</p><h3>Interview Question</h3><p><strong>Q: What’s the difference between </strong><strong>break inside </strong><strong>forEach and </strong><strong>break inside </strong><strong>for-in?</strong></p><p>In a for-in loop, break exits the loop immediately. In forEach, there is no break forEach takes a closure, and return inside it only exits the current closure call (equivalent to continue). You cannot exit a forEach loop early. If you need early exit, use for-in with break, or use first(where:) / contains(where:) depending on the goal.</p><h3>Summary</h3><ul><li>Use for-in for most loops it&#39;s clean, safe, and works on any Sequence.</li><li>Use enumerated() when you need both index and value.</li><li>Use zip() to loop two collections in parallel no index out of bounds risk.</li><li>Use stride when step size isn&#39;t 1.</li><li>Use while when iteration count is unknown upfront.</li><li>Use repeat-while when the body must execute at least once.</li><li>forEach doesn&#39;t support break or continue use for-in when you need flow control.</li><li>Labeled statements give precise control over nested loop exits.</li></ul><h3>Practice</h3><ol><li><strong>Beginner:</strong> Write a loop that prints the multiplication table for any number from 1 to 10 using stride.</li><li><strong>Intermediate:</strong> Given two arrays let userIDs = [1, 2, 3, 4, 5] and let userNames = [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Charlie&quot;, &quot;Diana&quot;, &quot;Eve&quot;] use zip and enumerated to print a numbered list of &quot;1. Alice (ID: 1)&quot;.</li><li><strong>Advanced:</strong> Write a function chunked&lt;T&gt;(_ array: [T], size: Int) -&gt; [[T]] that splits any array into chunks of a given size using a while loop. Handle edge cases: empty array, chunk size larger than array, chunk size of 1.</li></ol><h3>What’s Next</h3><p><strong>Article 6: Swift Functions Parameters, Return Types, Overloading, and First-Class Functions</strong></p><p>Loops move through data. Functions transform it. Next article covers everything about Swift functions default parameters, labeled arguments, variadic parameters, @discardableResult, inout parameters, and why functions are first-class citizens in Swift.</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 the </strong><strong>forEach vs </strong><strong>for-in difference saved you a future bug, tap 👏 up to 50 times, It helps this series reach developers who need it.</strong></p><p><strong>Follow me</strong> so Article 6 lands in your feed automatically. Each article in this series builds directly on the last.</p><p>See you in the next one. 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=750d27904ba9" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>