Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a custom NSURLProtocol on iOS for file:// URLs causes "Frame load interrupted" error

Tags:

ios

I want to load changing files into a UIWebView, and I want them to be loaded under the file:// scheme so I can include other file:// resources (such as html5 video elements) in my page. To do this I implement my own NSURLProtocol and override the loading of a subset of file:// URLs.

my startLoading method looks something like:

- (void) startLoading {
    ... data is populated ...
    [protocolClient URLProtocol:self didLoadData:data];
    [protocolClient URLProtocolDidFinishLoading:self];
}

This works fine on iOS4/5 but on iOS 6 beta 4 I get the following error:

2012-08-21 16:06:07.236 TemplateApp[57283:1d403] 57283: CFNetwork internal error (0xc01a:/SourceCache/CFNetwork_Sim/CFNetwork-606/Connection/URLConnectionClient.cpp:2341)
/SourceCache/WebCore_Sim/WebCore-1634/wak/WKView.mm:385 void WKViewAddSubview(WKViewRef, WKViewRef):  invalid parameter
2012-08-21 16:06:07.272 TemplateApp[57283:1e603] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSSetM addObject:]: object cannot be nil'
*** First throw call stack:
(0x29d0552 0x2733e7e 0x2a5dc08 0x69c6c1e 0x69c4c88 0x69c543b 0x5b40dbd 0x5b40f0f 0x5b3c240 0x5ff8060 0x5ff75d1 0x5eb8d08 0x65a4fb2 0x678486f 0x677fa3d 0x7b3ab1 0x7b2d63 0x7f0e5a 0x2972ebd 0x7f14dc 0x7f1455 0x6db410 0x29544ff 0x2953f2f 0x2976cf4 0x2976504 0x29763db 0x69d0530 0x907caed9 0x907ce6de)
libc++abi.dylib: terminate called throwing an exception

I resolved this by adding a didReceiveResponse call to my startLoading method as follows:

- (void) startLoading {
    ... data is populated ...
    [protocolClient URLProtocol:self didReceiveResponse:[[NSURLResponse alloc] init] cacheStoragePolicy:NSURLCacheStorageAllowed]
    [protocolClient URLProtocol:self didLoadData:data];
    [protocolClient URLProtocolDidFinishLoading:self];
}

However now on iOS 5 and 6 I get the following error when trying to load a page:

Webview error: Error Domain=WebKitErrorDomain Code=102 "Frame load interrupted" UserInfo=0x9d4c0a0 {NSErrorFailingURLKey=file:///src/index.html, NSErrorFailingURLStringKey=file:///src/index.html, NSLocalizedDescription=Frame load interrupted}

I have tried various different NSURLResponse objects in the didReceiveResponse method but none of them allowed the WebView to load the page. Using a URL scheme other than file:// also works but then I cannot use file:// paths for embedded resources such as HTML5 video.

Is there a way for me to load dynamic content for a specific file:// URL into a UIWebView which works on iOS 6 beta 4?

like image 266
Connorhd Avatar asked Aug 21 '12 15:08

Connorhd


2 Answers

I'm currently having some other issues with loading content into a UIWebView but I think you need to use NSURLResponse's initWithURL:MIMEType:expectedContentLength:textEncodingName:

Otherwise I don't think you have a valid response object. Problem I'm having is that I'm getting "bad URL", before my startLoading even gets called.

UPDATE: I got it working now, apparently my canonicalRequestForRequest: was goofy

like image 168
Russ Avatar answered Nov 15 '22 15:11

Russ


Ran into this as well. Here's a work-around that I think works, but doesn't work with history.back() and requires a global reference to the UIWebView.

- (void)startLoading {
    NSURL* insteadURL = ...;
    NSURLRequest* request = [self request];
    BOOL isTopLevelNavigation = [request.URL isEqual:request.mainDocumentURL];

    // iOS 6+ just gives "Frame load interrupted" when you try and feed it data via a URLProtocol.
    if (isTopLevelNavigation) {
        [gWebView loadData:[NSData dataWithContentsOfURL:insteadURL] MIMEType:@"text/html" textEncodingName:@"utf8" baseURL:[request URL]];
    } else {
        ...
    }
}
like image 26
GrieveAndrew Avatar answered Nov 15 '22 14:11

GrieveAndrew