Did you know that since iOS 2, there's a class included in Foundation
called NSURLProtocol
?
From the docs:
An NSURLProtocol object handles the loading of protocol-specific URL data. The NSURLProtocol class itself is an abstract class that provides the infrastructure for processing URLs with a specific URL scheme. You create subclasses for any custom protocols or URL schemes that your app supports.
Basically, it lets you implement a proxy for URL loading in your app. How does that help?
- I like to work offline — without connectivity to focus — sometimes. But most apps need to at least make a network request or two and fetch some data via an API call. You can use
NSURLProtocol
to do just that. - Alternatively, you might be have automated tests that makes network calls. You'll generally want those to be deterministic and playing back a known, static version using
NSURLProtocol
is very useful.
There's a library that does just that — VCRURLConnection. From the README, here's how you make a recording:
[VCR start];
NSString *path = @"http://example.com/example";
NSURL *url = [NSURL URLWithString:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// use either NSURLSession or NSURLConnection
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request];
[task resume];
// NSURLSession makes a real network request and VCRURLConnection
// will record the request/response pair.
// once async request is complete or application is ready to exit:
[VCR save:@"/path/to/cassette.json"]; // copy the output file into your project
You can play it back with:
NSURL *cassetteURL = [NSURL fileURLWithPath:@"/path/to/cassette.json"];
[VCR loadCassetteWithContentsOfURL:cassetteURL];
[VCR start];
// request an HTTP interaction that was recorded to cassette.json
NSString *path = @"http://example.com/example";
NSURL *url = [NSURL URLWithString:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// use either NSURLSession or NSURLConnection
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request];
[task resume];
// The cassette has a recording for this request, so no network request
// is made. Instead NSURLConnectionDelegate methods are called with the
// previously recorded response.
It's available over Carthage and Cocoapods. Pretty handy isn't it?
Your feedback is valuable: Do you want more nuggets like this? Yes or No
.
.