Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURLProtocol's abstract methods

I have been using a custom NSURLProtocol in my app to detect resources and load from a cache directory if available, or redirect back to my app's server. However, I am finding the documentation on the abstract methods to be lacking and I am not sure what to do with some of the abstract methods which we are required to implement.

We must implement:

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
- (void)startLoading
- (void)stopLoading

canInitWithRequest is easy, this is how you tell the NSURLProtocol that you will respond to this request.

I have no idea what to do with canonicalRequestForRequest:.

In startLoading:, I have been either creating my response from a local file or synchroniously fetching a remote file, then calling the client methods:

[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
[self.client URLProtocol:self didLoadData:responseData];
[self.client URLProtocolDidFinishLoading:self];

It is unclear to me if I need to call the client protocol method:

 - (void)URLProtocol:(NSURLProtocol *)protocol wasRedirectedToRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse

When I decide to fetch the resource from the remote server (when it hasn't yet been cached).

Lastly, I haven't yet figured out what to do with stopLoading:

If anyone knows more of what these methods are expected to do, your insights are very much appreciated.

like image 535
rich.e Avatar asked Sep 19 '11 05:09

rich.e


1 Answers

canonicalRequestForRequest - From the docs (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLProtocol_Class/Reference/Reference.html)

"It is up to each concrete protocol implementation to define what “canonical” means. A protocol should guarantee that the same input request always yields the same canonical form.

Special consideration should be given when implementing this method, because the canonical form of a request is used to lookup objects in the URL cache, a process which performs equality checks between NSURLRequest objects."

All it's saying is:

Make sure that two requests that are EFFECTIVELY the same URL ... end up using EXACTLY the same request-string

...so that requesting one will return the pre-cached version of the other, if available.

You should be OK to simply return the request back again. You could finesse it by checking for characters that don't need to be URLencoded but are (e.g. if there's a literal dash / hyphen encoded).


wasRedirectedToRequest - from the docs (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSURLProtocolClient_Protocol/Reference/Reference.html)

"Sent to indicate to the URL loading system that the protocol implementation has been redirected. (required)"

i.e. you ONLY call this if the request got redirected via an HTTP redirect code (e.g. a 30x status code).

NOTE: BUGS IN STACKOVERFLOW MEAN I CANNOT TYPE WHAT I WANTED HERE

For instance, a server might redirect "http:// server" to "http:// server/index.html" - and this callback lets you inform the receiver that it's going to get a response from a slightly different URL than the one it asked for.

Again, this is necessary for doing correct caching etc.

like image 90
Adam Avatar answered Oct 20 '22 04:10

Adam