Similar questions have been asked before, but I could never find a solution.
Here is my situation - my UIWebView loads a remote html page. The images used in the web
Nick Weaver has the right idea but the code in his answer does not work. It breaks some naming conventions as well, never name your own classes with the NS prefix, and follow the convention of capitalizing acronyms such as URL in identifier names. I'll stick w/ his naming in the interest of making this easy to follow.
The changes are subtle but important: lose the unassigned request ivar and instead refer to the the actual request provided by NSURLProtocol and it works fine.
NSURLProtocolCustom.h
@interface NSURLProtocolCustom : NSURLProtocol
@end
NSURLProtocolCustom.m
#import "NSURLProtocolCustom.h"
@implementation NSURLProtocolCustom
+ (BOOL)canInitWithRequest:(NSURLRequest*)theRequest
{
if ([theRequest.URL.scheme caseInsensitiveCompare:@"myapp"] == NSOrderedSame) {
return YES;
}
return NO;
}
+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)theRequest
{
return theRequest;
}
- (void)startLoading
{
NSLog(@"%@", self.request.URL);
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:self.request.URL
MIMEType:@"image/png"
expectedContentLength:-1
textEncodingName:nil];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"image1" ofType:@"png"];
NSData *data = [NSData dataWithContentsOfFile:imagePath];
[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
[[self client] URLProtocol:self didLoadData:data];
[[self client] URLProtocolDidFinishLoading:self];
[response release];
}
- (void)stopLoading
{
NSLog(@"request cancelled. stop loading the response, if possible");
}
@end
The problem with Nick's code is that subclasses of NSURLProtocol do not need to store the request. NSURLProtocol already has the request and you can access with the method -[NSURLProtocol request] or the property of the same name. Since the request ivar in his original code is never assigned it is always nil (and if it was assigned it should have been released somewhere). That code cannot and does not work.
Second, I recommend reading the file data before creating the response and passing [data length] as the expected content length instead of -1.
And finally, -[NSURLProtocol stopLoading] is not necessarily an error, it just means you should stop work on a response, if possible. The user may have cancelled it.