title: How to mock AJAX call with NSURLProtocol?
body: <p>I have UIWebview that makes AJAX calls to external services. When offline i need to catch theses requests and return local json.</p>
  
  <p>I implemented a NSURLProtocol and i manage to catch the AJAX request, the problem is jquery always return a 0 error code :</p>
  
  <pre><code>$.ajax({
    url: url,
    dataType: 'json',
    contentType: "application/json",
    success: function(jsonData){
      alert("success :");
    },
    error: function (request, status, error) {
      alert("failure :" + request.status );
    }
  </code></pre>
  
  <p>});</p>
  
  <p>I always get a request.status = 0</p>
  
  <p>To test my protocol I tried to mock an image inside my html and it works great.</p>
  
  <ul>
  <li>HTML request to an image from google.fr => <strong>works fine</strong></li>
  <li>AJAX call to a json on amazon => <strong>fails</strong></li>
  </ul>
  
  <p>Here is my full implementation :</p>
  
  <pre><code>#import "EpubProtocol.h"
  
  @implementation EpubProtocol
  
  #pragma mark - NSURLProtocol
  
  + (BOOL)canInitWithRequest:(NSURLRequest *)request {
      BOOL awsRequest = [self request:request contains:@"s3.amazonaws.com"];
      BOOL imgRequest = [self request:request contains:@"google.fr"];
      BOOL match = awsRequest || imgRequest;
  
      return match;
  }
  
  
  + (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)theRequest
  {
      return theRequest;
  }
  
  
  - (void)startLoading {
      NSURLRequest *request = [self request];
  
      //Mock Amazon call
      if([EpubProtocol request:request contains:@"s3.amazonaws.com"]) {
          NSString *path = [[NSBundle bundleForClass:self.class] pathForResource:@"epub1" ofType:@"json"];
          NSData *data = [NSData dataWithContentsOfFile:path];
  
          [self mockRequest:request mimeType:@"application/json" data:data];
      }
      //Mock image call
      else if([EpubProtocol request:request contains:@"google.fr"]) {
          NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  
          [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.itespresso.fr/wp-content/gallery/yahoo/1-yahoo-logo.jpg"]] queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
              [self mockRequest:request mimeType:@"image/jpeg" data:data];
          }];
      }
  }
  
  - (void)stopLoading
  {
      NSLog(@"Did stop loading");
  }
  
  
  #pragma mark - Request utils
  
  + (BOOL) request:(NSURLRequest*)request contains:(NSString*)domain {
      NSString *str = [[request URL] absoluteString];
      NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", domain];
      return [pred evaluateWithObject:str];
  }
  
  
  #pragma mark - Mock responses
  
  
  -(void) mockRequest:(NSURLRequest*)request mimeType:(NSString*)mimeType data:(NSData*)data {
      id client = [self client];
  
      NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[request URL] MIMEType:mimeType expectedContentLength:-1 textEncodingName:nil];
  
      [client URLProtocol:self didReceiveResponse:response
       cacheStoragePolicy:NSURLCacheStorageNotAllowed];
      [client URLProtocol:self didLoadData:data];
      [client URLProtocolDidFinishLoading:self];
  }
  
  @end
  </code></pre>