Dynamically loading javascript files in UIWebView with local cache not working

后端 未结 1 432
一整个雨季
一整个雨季 2020-12-15 01:39

I\'m trying to write an application which uses a lot of java script inside a UIWebView. And some of this java script is loaded dynamically (with jquery) when it is needed.

相关标签:
1条回答
  • 2020-12-15 02:18

    After some more more work I found the solution to my problem. And answer here with what I found.

    The solution is to to create a custom NSURLProtocol implementation and register this in the application as handler for the http protocol. The code looks like this (I've omitted some error handling in the code):

    #import "MyHttpURLProtocol.h"
    
    @implementation MyHttpURLProtocol
    
    + (BOOL)canInitWithRequest:(NSURLRequest *)request {
        return [[[request URL] scheme] isEqualToString:@"http"]; // we handle http requests
    }
    
    + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
        return request;
    }
    
    - (void) startLoading {
        id<NSURLProtocolClient> client = [self client];
        NSURLRequest* request = [self request];
        NSString *pathString = [[request URL] absoluteString];
    
        NSString* fileToLoad = nil;
        if ([pathString isEqualToString:@"http://example.com/index.html"]) {
            fileToLoad = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
        }
        else if ([pathString hasPrefix:@"http://example.com/code.js"]) {
            fileToLoad = [[NSBundle mainBundle] pathForResource:@"code" ofType:@"js"];
        }
        else if ([pathString isEqualToString:@"http://example.com/jquery-1.6.2.min.js"]) {
            fileToLoad = [[NSBundle mainBundle] pathForResource:@"jquery-1.6.2.min" ofType:@"js"];
        }
    
        NSData* data = [NSData dataWithContentsOfFile:fileToLoad];
    
        NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc] initWithURL:[request URL] statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:[NSDictionary dictionary]];
    
        [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
        [client URLProtocol:self didLoadData:data];
        [client URLProtocolDidFinishLoading:self];
    }
    
    - (void) stopLoading {}
    
    @end
    

    This code allows now to load the index.html file be accessing the following code:

    [_webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/index.html"]]];
    

    And don't forget to register the custom protocol in your app delegate:

    [NSURLProtocol registerClass:[TOHttpURLProtocol class]];

    [NSURLProtocol registerClass:[MyHttpURLProtocol class]];
    

    It's amazing how simple the solution can be after your found it. Here is the link to the updated example project: http://dl.dropbox.com/u/5426092/LocalCacheJsInjectTest-working.zip

    And for completeness sake here is the link to the blog post which helped me in finding the solution: http://www.infinite-loop.dk/blog/2011/09/using-nsurlprotocol-for-injecting-test-data/

    0 讨论(0)
提交回复
热议问题