Episode #190

Custom URL Protocols

15 minutes
Published on October 1, 2015

This video is only available to subscribers. Get access to this video and 572 others.

In this episode we look at how to create a custom NSURLProtocol to intercept and alter a network request. This can be useful to provide application-wide interception & logging of network requests, alter requests to change parameters or add authentication, sign requests, or to handle custom url schemes.

There is a newer version of this episode here:
Faking an API Server with URLProtocol

Note that since this episode was released, NSURLProtocol is now URLProtocol in Swift

Episode Links

Creating a custom protocol

Create a class that derives from NSURLProtocol and implements these four methods:

class CustomProtocol : NSURLProtocol {
    override class func canInitWithRequest(request: NSURLRequest) -> Bool {
      // ...
    }

    override class func canonicalRequestForRequest(request: NSURLRequest) -> NSURLRequest {
      // ...
    }

    override func startLoading() {
      // ...
    }

    override func stopLoading() {
      // ...
    }
}

Then make sure to register the new protocol:

NSURLProtocol.registerClass(CustomProtocol.self)

Avoiding Infinite Loops

It's important to make sure that you don't handle requests that have already been intercepted, to avoid an infinite loop. To do this, you can either:

  • Alter the request in a way that you can tell by looking at the URL or Params, such as with a custom scheme
  • Add a "tag" to the request so you can check it here

Setting a custom property, or "tag" on a request looks like this:

  CustomProtocol.setProperty(true, forKey: "CustomProtocolHandled", inRequest: req)

We can set this when we send out a request, and check for it again in +canInitWithRequest: like this:

  if propertyForKey("CustomProtocolHandled", inRequest: request) != nil {
    return false
  }