NSURLProtocol Tutorial

NSURLProtocol is the lesser known heart of the URL handling system in iOS. In this NSURLProtocol tutorial you will learn how to tame it. By Rocir Santiago.

Leave a rating/review
Save for later
Share

Learn how to harness the power of NSURLProtocol!

NSURLProtocol Tutorial

Update 9/3/14: This tutorial has now been updated for iOS 8 and Swift; check it out!

NSURLProtocol is like a magic key to the URL. It lets you redefine how Apple’s URL Loading System operates, by defining custom URL schemes and redefining the behavior of existing URL schemes.

Does that sound magical? It should. Because, if you look for it, I’ve got a sneaky feeliing you’ll find URLs — much like love — are all around us. What does UIWebView use? URLs. What’s used for video streaming with MPMoviePlayer? URLs. How do you send someone to your app on iTunes, initiate FaceTime or Skype, launch another app on the system, or even embed an image in an HTML file? With a URL. Have a peek at NSFileManager and notice what many of its file-manipulation methods require and return — URLs.

NSURLProtocol is awesome because it lets your app speak the language of love…um, URLs. It can also be used to make deep changes to how they are processed. You can add new networking protocols that existing URL-based components and libraries can automatically use. Or, you can modify how existing protocols work. For instance, you can log all network requests, modify outgoing and incoming information streams or service some requests differently and transparently, e.g., from a cache.

By default, iOS URL Loading System supports the following schemes:

  • ftp:// for File Transfer Protocol
  • http:// for Hypertext Transfer Protocol
  • https:// for Hypertext Transfer Protocol with encryption
  • file:// for local file URLs
  • data:// for data URLs

In this NSURLProtocol tutorial, you’ll learn how to define a protocol handler that modifies URL schemes. It will add a rough and ready transparent caching layer, by storing retrieved resources in Core Data. By enabling it, an ordinary UIWebView can then take on the role of a browser by caching downloaded pages for offline viewing at a later time.

Before you dive in head first, you’ll need a basic understanding of networking concepts and familiarity with how NSURLConnection works. If you are not currently familiar with NSURLConnection then I suggest reading this tutorial and/or this document by Apple.

However, nothing about NSURLProtocol is specific to NSURLConnection. You can implement a custom protocol that uses:

  • Lower level networking primitives
  • Just the filesystem
  • Or pure computation.

Custom protocols can configure the behavior of NSURLConnection, and also of the new NSURLSession-based networking facilities. Cool!

So are you ready to learn what you can do with NSURLProtocol? Good, go pour yourself a cuppa something and settle in for a meaty, mind-broadening discussion and step-by step exercise. The first thing to discuss in what it is and how it works.

What Is NSURLProtocol?

A set of classes known as the URL Loading System, handles URL requests. You need to know them to find out how iOS handles your app’s requests to load a URL-based resource.

At the heart of the URL Loading System is the NSURL class. For network requests, this class tells what host your app is trying to reach and path to the resource at that host. In addition the NSURLRequest object adds information like HTTP headers, the body of your message, etc.. The loading system provides a few different classes you can use to process the request, the most common being NSURLConnection and NSURLSession.

When you receive a response it comes back in two parts: metadata and data. The metadata is encapsulated in a NSURLResponse object. It will tell you the MIME type, the text encoding (when applicable), the expected amount of data of your response and the URL that is the source of the information. The data arrives as NSData objects.

Behind the scenes, when the loading system downloads information using a NSURLRequest, it will create an instance of a NSURLProtocol subclass, which represents your custom URL protocol. NSURLProtocol is an abstract class that exists only to be extended in this way. You should never instantiate an NSURLProtocol object directly.

Note: Remember that Objective-C doesn’t actually have abstract classes as a first class citizen. It’s only by definition and documentation that a class is marked as abstract.

Given the name of NSURLProtocol you could be forgiven for thinking that it’s an Objective-C protocol. Strangely, it isn’t. It’s a class. But it is used in a way that is very similar to a protocol as it’s defining a set of methods that must be implemented by something that conforms to NSURLProtocol. A protocol was probably not flexible enough for Apple, so they chose to use an abstract base class.

When a subclass of NSURLProtocol handles a request, it’s the subclass’ job to create the NSURLResponse objects to encapsulate the response. Once you have registered your own NSURLProtocol, the loading system will search for the first one equipped to handle a specific NSURLRequest.

When To Use NSURLProtocol?

How can you use NSURLProtocol to make your app cooler, faster, stronger and jaw-droppingly awesome? Here are a few examples:

Provide Custom Responses For Your Network Requests:

It doesn’t matter if you’re making a request using a UIWebView, NSURLConnection or even using a third-party library (like AFNetworking, MKNetworkKit, your own, etc, as these are all built on top of NSURLConnection). You can provide a custom response, both for metadata and for data. You might use this if you wanted to stub out the response of a request for testing purposes, for example.

Skip Network Activity and Provide Local Data:

Sometimes you may think it’s unnecessary to fire a network request to provide the app whatever data it needs. NSURLProtocol can set your app up to find data on local storage or in a local database.

Redirect Your Network Requests:

Have you ever wished you could redirect requests to a proxy server — without trusting the user to follow specific iOS setup directions? Well, you can! NSURLProtocol gives you what you want — control over requests. You can set up your app to intercept and redirect them to another server or proxy, or wherever you want to. Talk about control!!

Change the User-agent of Your Requests:

Before firing any network request, you can decide to change its metadata or data. For instance, you may want to change the user-agent. This could be useful if your server changes content based on the user-agent. An example of this would be differences between the content returned for mobile versus desktop, or the client’s language.

Use Your Own Networking Protocol:

You may have your own networking protocol (for instance, something built on top of UDP). You can implement it and, in your application, you still can can keep using any networking library you prefer.

Needless to say, the possibilities are many. It would be impractical (but not impossible) to list all the possibilities you have with NSURLProtocol in this tutorial. You can do anything you need with a given NSURLRequest before it’s fired by changing the designated NSURLResponse. Better yet, just create your own NSURLResponse. You’re the developer, after all.

While NSURLProtocol is powerful, remember that it’s not a networking library. It’s a tool you can use in addition to the library you already use. In short, you can take advantage of NSURLProtocol‘s benefits while you use your own library.

Right, now on to some code…

Rocir Santiago

Contributors

Rocir Santiago

Author

Over 300 content creators. Join our team.