Custom URL Protocols

Episode #190 | 15 minutes | published on October 1, 2015
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.

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
  }
blog comments powered by Disqus