1

Let's go straight into code.

First in appDelegate, I register my connection protocol:

[NSURLProtocol registerClass:[MyURLConnection class]];

Here's what my connection class looks like:

+(BOOL)canInitWithRequest:(NSURLRequest *)request {
  return YES;
}

-(void)startLoading {
  if (self.cachedResponse) {
    NSLog(@"there is a cached response %@", self.cachedResponse);
  }

  MyNetworkSession *task = [MyNetworkSession new];
  task.request = self.request;
  task.urlClient = self.client;
  task.isDataTask = YES;
  task.isBackgroundSession = YES;
  [task start];
}

-(void)stopLoading {
  // nothing here
}

Now, MyNetworkSession is the delegate for NSURLSession tasks, like so:

// ----------- MyNetworkSession.h
 @interface MyNetworkSession : NSObject
 <NSURLSessionDelegate,
 NSURLSessionTaskDelegate,
 NSURLSessionDataDelegate>

 -(void) start;

 @end


 //------------ MyNetworkSession.m
 @implementation MyNetworkSession {
   NSURLSessionDataTask *_dataTask;
   NSURLSessionDownloadTask *_downloadTask;
 }

 // create session
 -(NSURLSession*) session {
   static NSURLSession *session = nil;
   static dispatch_once_t onceToken;
   dispatch_once(&onceToken, ^{
       NSURLSessionConfiguration *backgroundConfiguration = [
       NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:
          BACKGROUND_SESSION_IDENTIFIER];

       backgroundConfiguration.requestCachePolicy = NSURLRequestUseProtocolCachePolicy;
       session = [NSURLSession
         sessionWithConfiguration:backgroundConfiguration
         delegate:self
         delegateQueue:nil];
    });

   return session;
}

 // start download/data task
-(void)start {
   if (self.isDataTask){
    _dataTask = [self.session dataTaskWithRequest:self.request];
    [_dataTask resume];
  }
}

#pragma mark- delegate methods
-(void)URLSession:(NSURLSession *)session
  task:(NSURLSessionTask *)task
   didCompleteWithError:(NSError *)error {

  if (error) {
     NSLog(@"Error in connection %@ for task %@", error, task.response.URL);
  }

  NSLog(@"completed response %@", task.response.URL.absoluteString);
   _dataTask = nil;
   _downloadTask = nil;
   [self.urlClient URLProtocolDidFinishLoading:self.urlClient];
 }

 -(void)URLSession:(NSURLSession *)session
   dataTask:(NSURLSessionDataTask *)dataTask
   didReceiveResponse:(NSURLResponse *)response
   completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {

   NSLog(@"received response %@", response.URL.absoluteString);

   [self.urlClient URLProtocol:self.urlClient
   didReceiveResponse:responsecacheStoragePolicy:NSURLCacheStorageAllowedInMemoryOnly];

   completionHandler(NSURLSessionResponseAllow);
 }

-(void)URLSession:(NSURLSession *)session
   dataTask:(NSURLSessionDataTask *)dataTask
   didReceiveData:(NSData *)data {

  NSLog(@"received data %@", dataTask.response.URL.absoluteString);
  if (!self.data) {
      self.data = [data mutableCopy];
  } else {
      [self.data appendData:data];
  }

  [self.urlClient URLProtocol:self.urlClient didLoadData:self.data];
}

//... some more methods

@end

That's all the relevant code I guess.

The problem is that when I see the response in a webview, I only get the <head> tag of the document.

I am not getting the rest of the html. And also, the js/css files listed in the <head> tag are not downloaded. Do you see any flaw in the implementation?

Fabio Berger
  • 1,921
  • 2
  • 24
  • 29
Parag
  • 963
  • 2
  • 10
  • 27

0 Answers0