All articles
iOS2 min read

Swift URLProtocol Explained in 3 Minutes (With Real Example for Testing)

Want to mock network calls in Swift without setting up a mock server or third-party tool?

K
Karan Pal
Author
Image generated by AI
Image generated by AI

Let’s talk about URLProtocol.

Yes, it sounds low-level. But it’s one of the cleanest, most powerful ways to test URLSession — and it’s built right into Foundation.

🚦 What Is URLProtocol?

Think of it as an interceptor for all network traffic made through a URLSession.

With it, you can:

🔧 Real Use Case: Testing Your API Client Without Internet

Here’s a test scenario:

All without changing your production code or using third-party libraries.

Here’s how 👇

🛠️ Code Snippet: Minimal Setup

class URLProtocolStub: URLProtocol {
    static var stub: (Data?, URLResponse?, Error?)?

    override class func canInit(with request: URLRequest) -> Bool { true }

    override func startLoading() {
        if let data = stub?.0 {
            client?.urlProtocol(self, didLoad: data)
        }
        if let response = stub?.1 {
            client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)
        }
        if let error = stub?.2 {
            client?.urlProtocol(self, didFailWithError: error)
        }
        client?.urlProtocolDidFinishLoading(self)
    }

    override func stopLoading() {}
}

🧪 Step 2: Simulating a 401 Unauthorized

URLProtocolStub.stub = (
    data: nil,
    response: HTTPURLResponse(
        url: URL(string: "https://api.example.com/protected")!,
        statusCode: 401,
        httpVersion: nil,
        headerFields: nil
    ),
    error: nil
)

let config = URLSessionConfiguration.ephemeral
config.protocolClasses = [URLProtocolStub.self]
let session = URLSession(configuration: config)

You now have a URLSession that will always return a 401 Unauthorized, just like a real expired token response 🎯

🧠 Why This Rocks

✅ No real API required

✅ Works offline

✅ Tests error paths, not just happy flows

✅ Pairs perfectly with async/await + your own NetworkClient abstraction

💡 Final Thought

If you’re testing a networking layer, URLProtocol gives you full control — without bloating your test suite with mocks or hitting live servers.

It’s clean. It’s native. And it just works 💪

🎉 Enjoyed this article? Your support means the world to me!

💬 Drop a comment below! I love hearing about your experiences and answering questions

🎬 Subscribe on Youtube and become early subscribers of my channel: https://www.youtube.com/@swift-pal

💼 Let’s connect on LinkedIn for more professional insights: https://www.linkedin.com/in/karan-pal

Happy coding! 🚀

● The newsletter

New articles, straight to your inbox.

No spam, no filler — just new writing on iOS, the web, and AI when it ships. Unsubscribe anytime.

Keep reading