3

Since upgrading to iOS 9.1 my custom NSURLProtocol, won't invoke -(void)startLoading anymore. Has anyone else experienced this ?

Everything worked fine on iOS 8 ...

Code:

@implementation RZCustomProtocol
@dynamic request;

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    if ([request.URL.scheme isEqualToString:@"imsweb"]) {
        NSLog(@"%@", @"YES");
        return YES;
    }
    return NO;
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
    return request;
}

+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b {
    return [super requestIsCacheEquivalent:a toRequest:b];
}

- (void)startLoading {
    NSLog(@"STARTLOADING: %@", [self.request.URL absoluteString]);
    NSString *filename = [[self.request.URL lastPathComponent] stringByDeletingPathExtension];
    NSLog(@"%@", filename);
    NSString *videoUrl = [[NSBundle mainBundle] pathForResource:filename ofType:@"mp4"];
    NSData *video = [NSData dataWithContentsOfFile:videoUrl];
    NSLog(@"%lu", (unsigned long)video.length);
    NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:self.request.URL
                                                              statusCode:200 HTTPVersion:nil headerFields:@{
                                                                                                            @"Content-Length": [NSString stringWithFormat:@"%lu", (unsigned long)video.length],
                                                                                                            @"Content-Type": @"video/mp4",
                                                                                                            }];

    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    [self.client URLProtocol:self didLoadData:video];
    [self.client URLProtocolDidFinishLoading:self];
}

- (void)stopLoading {
    NSLog(@"STOPLOADING: %@", [self.request.URL absoluteString]);
}
strangfeld
  • 1,067
  • 1
  • 9
  • 16
  • Check [this thread](http://stackoverflow.com/questions/26390036/nsurlprotocol-isnt-asked-to-load-after-yes-response-to-caninitwithrequest) out. This may help you! – Abhinav Oct 24 '15 at 14:02
  • @Abhinav thank you, but startLoading() ist not even called once. – strangfeld Oct 24 '15 at 15:04

1 Answers1

1

I had the same issue. In my case, I was adding an iframe to the page dynamically using JavaScript and loading my custom protocol content in that. In iOS 9.1 the WebView refuses to load the iframe content when the main document is accessed over https, but it works fine over http. This looks like a new security control, to avoid loading insecure resources over a secure session.

The fix I went with was to change my scheme to use https. For example, use https://imsweb/... instead of imsweb://. It's a bit of a hack but the best solution I could find.

Something like:

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    if ([request.URL.scheme isEqualToString:@"https"] &&
            [request.URL.host isEqualToString:@"imsweb"]) {
        NSLog(@"%@", @"YES");
        return YES;
    }
    return NO;
}

and of course you need to reconstruct the correct URL in startLoading.

Paul
  • 26
  • 3
  • This could be a possible solution, but unfortunately i will not be able to test this anymore. For the use case: We had a booth at a fair, where the internet connection was too slow for streaming it from our media server. So my solution was to host this media server on my laptop together with a proxy. Then i connected the iPads to the proxy and forwarded the media requests to this local instance, while passing the rest to the internet. Since this works for you, I mark it as solution. – strangfeld Nov 18 '15 at 13:07