Swift
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Optionals
-
Section 4: Object-Oriented and Value Types
-
Section 5: Memory Management
-
Section 6: Generics and Error Handling
-
Section 7: Concurrency
-
Section 8: Working with Collections
-
Section 9: Codable and Data Handling
-
Section 10: Protocol-Oriented Programming
-
Section 11: Testing and Tooling
-
Section 12: Practical Projects
-
Section 13: Interview Practice
-
Section 14: More Practice Exercises
-
Section 15: More Standard Library
-
Section 16: Advanced Concurrency
-
Section 17: Foundation Framework Deep Dive
-
Section 18: URLSession and Networking Deep Dive
-
Section 19: Combine Framework
-
Section 20: SwiftUI Fundamentals for Swift Developers
-
Section 21: Server-Side Swift with Vapor
-
Section 22: Swift Package Manager Deep Dive
-
Section 23: Swift Concurrency Deep Dive
-
Section 24: More Language Features
-
Section 25: Error Handling Deep Dive
-
Section 26: Testing Deep Dive
-
Section 27: Data Structures and Algorithms in Swift
-
Section 28: More Practice Exercises
-
Section 29: More Interview Practice
-
Section 30: Swift Macros (Swift 5.9+)
-
Section 31: Property Wrappers Ecosystem
-
Section 32: Swift Interop Deep Dive
-
Section 33: iOS App Architecture Patterns
-
Section 34: Performance and Debugging
-
Section 35: App Distribution and CI/CD
-
Section 36: More Practical Projects
-
Section 37: SwiftData and Persistence
-
Section 38: More Design Patterns
-
Section 39: More Review and Practice
-
Section 40: More Foundation Deep Dive
-
Section 41: Advanced Collections in Swift
-
Section 42: Advanced Generics Practice
-
Section 43: UIKit for Legacy and Hybrid Apps
-
Section 44: watchOS and visionOS Development Basics
-
Section 45: More Networking Patterns
-
Section 46: More Testing Practice
-
Section 47: Accessibility in Swift Apps
-
Section 48: Localization
-
Section 49: More Practical Projects Round 2
-
Section 50: Swift Charts Framework
-
Section 51: More Interview and Algorithm Practice
-
Section 52: Final Practice and Mastery
-
Section 53: Swift Compiler and Build System
-
Section 54: More Concurrency Practice
-
Section 55: App Store Guidelines and Review
-
Section 56: More Design and Architecture
80: URLSession Configuration Types
Most of us start our Swift networking journey using URLSession.shared. It’s convenient, it's right there, and for a simple GET request to a public API, it works perfectly. But the shared session is essentially a "black box" with a set of opinions you can't change. It uses a default configuration that assumes you want your cookies, caches, and credentials stored on disk indefinitely. In a professional app, that "one size fits all" approach usually becomes a liability pretty quickly.
The trap of the shared session
Imagine you're building a banking app or a secure health portal. You have a "Private Mode" where the user wants to ensure that no sensitive data—like session cookies or cached responses—is left sitting in the app's sandbox on the device. If you stick with URLSession.shared, you're stuck. You can't tell the shared session to stop caching or to wipe its cookies for a specific set of requests because the shared session is a singleton; changing it for one request changes it for the entire app.
// The naive way: Global and uncontrollable
let data = try await URLSession.shared.data(from: secureURL)
// Everything here is cached to disk by default. Not great for privacy.
The better way is to stop relying on the singleton and start using URLSessionConfiguration. By creating your own configuration, you're essentially telling the OS, "I want a session that behaves exactly like this," rather than accepting whatever the default is. For a privacy-focused flow, we use .ephemeral.
Wiping the digital footprint with Ephemeral configurations
When you use URLSessionConfiguration.ephemeral, you're telling Swift to keep everything in RAM. No cookies are written to disk, and no cache files are created in the file system. When the session is invalidated, that data simply vanishes. It's the networking equivalent of an Incognito tab.
// The professional way: Tailored for privacy
let config = URLSessionConfiguration.ephemeral
config.allowsCellularAccess = false // I can even tweak specific behaviors here
let session = URLSession(configuration: config)
let (data, response) = try await session.data(from: secureURL)
// Now, nothing sensitive hit the disk.
The trade-off here is performance. Because you've opted out of disk caching, the app will have to re-download resources that a .default configuration would have pulled from the local cache. For a login screen or a secure profile page, that's a price I'm always willing to pay for security. For a high-resolution image gallery, it would be a disaster.
Surviving the app switch with Background configurations
Then there's the problem of longevity. Let's say your app allows users to download a 200MB PDF manual. If you use .default or .ephemeral, the moment the user swipes up to check their email or the OS decides your app has been in the background too long, the system will likely kill your network task to save power. The download just stops, and your user is left with a half-finished file.
This is where URLSessionConfiguration.background(withIdentifier:) comes in. This is a completely different beast. When you use a background configuration, you're handing the actual transfer over to the system daemon. Even if your app crashes or is terminated by the OS, the download continues in the background. When it finishes, the OS wakes your app up to handle the completed file.
I'll be honest: background sessions are a bit of a pain to implement. You can't use the simple async/await data methods because the app might not even be running when the data arrives. You have to go back to using delegate methods to track progress. It's more boilerplate, but it's the only way to ensure a reliable user experience for large files. If you try to "hack" this by using a foreground session and hoping for the best, you'll find your app's reliability plummeting as soon as you test it on a real device with a spotty connection.
📋 Practical Task
Exercise: Implementing a Privacy-Toggle Network Manager
Build a NetworkManager class that can switch between "Standard" and "Private" modes. Your implementation should meet the following requirements:
- Create an enum
SessionModewith casesstandardandprivate. - Implement a method
fetchData(from url: URL, mode: SessionMode) async throws -> Data. - If the mode is
.standard, the method should use aURLSessioninitialized with.defaultconfiguration. - If the mode is
.private, it must use aURLSessioninitialized with.ephemeralconfiguration. - To avoid creating a new session for every single request (which is expensive), implement a simple caching mechanism within your manager that stores one
standardSessionand oneprivateSessionand reuses them.
There are no comments for now.