Loading javascript into a UIWebView from resources

pyramation picture pyramation · Apr 20, 2011 · Viewed 49.1k times · Source

I need to load javascript files from my apps resources folder. As of right now, it does read images from the resources just fine, but it's not reading javascripts for some reason.

I have been able to render html docs that reference these javascripts if the html files themselves are written into the resources, but I would like to render html/js by setting the html of a UIWebView so it can be dynamic.

Here is what I am doing:

NSString * html = @"<!DOCTYPE html><html><head><title>MathJax</title></head><body><script type=\"text/x-mathjax-config\">MathJax.Hub.Config({tex2jax: {inlineMath: [[\"$\",\"$\"],[\"\\(\",\"\\)\"]]}});</script><script type=\"text/javascript\" src=\"/MathJax/MathJax.js\"></script>$$\\int_x^y f(x) dx$$<img src=\"coffee.png\"></body></html>";

NSString * path = [[NSBundle mainBundle] resourcePath]; 
path = [path stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
path = [path stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

NSString * resourcesPath = [[NSString alloc] initWithFormat:@"file://%@/", path];
[webview loadHTMLString:html baseURL:[NSURL URLWithString:resourcesPath]];

Now, if I change the base url to my server which also has the required files, it does load correctly. It would be great to not require an internet connection. Any help is appreciated!!! ;)

I found this useful in getting images to display: iPhone Dev: UIWebView baseUrl to resources in Documents folder not App bundle

Edit:

Instead of doing the string replacing and URL encoding, I was able to get images to by simply calling resourceURL on the mainBundle, but still no javascript execution.

    NSString * setHtml = @"<!DOCTYPE html><html><head><title>MathJax</title></head><body><script type=\"text/x-mathjax-config\">MathJax.Hub.Config({tex2jax: {inlineMath: [[\"$\",\"$\"],[\"\\(\",\"\\)\"]]}});</script><script type=\"text/javascript\" src=\"/MathJax/MathJax.js\"></script>$$\\int_x^y f(x) dx$$<img src=\"images/test.png\"></body></html>";
    [webview loadHTMLString:setHtml baseURL:[[NSBundle mainBundle] resourceURL]];

EDIT

If you want to help give this a shot, I have made it easier for you by creating an example project!

https://github.com/pyramation/math-test

git clone [email protected]:pyramation/math-test.git

Answer

Nick Weaver picture Nick Weaver · Apr 27, 2011

Here we go with a simple setup.

Create the following folder structure in your Resources folder.

Note that the blue folders are referenced ones

enter image description here

The css is just candy :) In lib.js resides your javascript code which you'd like to use.

index.html

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="css/standard.css">

        <script src="js/lib.js" type="text/javascript" />
    </head>
    <body>
        <h2>Local Javascript</h2>

        <a href="javascript:alert('Works!')">Test Javascript Alert</a>      

        <br/>
        <br/>

        <a href="javascript:alertMeWithMyCustomFunction('I am');">External js test</a>
    </body>
</html>

lib.js

function alertMeWithMyCustomFunction(text) {
    alert(text+' -> in lib.js');
}

Loading of the content in the webview

Note: webView is a property, view created with instance builder

- (void)viewDidLoad
{   
    NSString *htmlPath = [[NSBundle mainBundle] pathForResource:@"index" 
                                                         ofType:@"html" 
                                                    inDirectory:@"/htdocs" ];

    NSString *html = [NSString stringWithContentsOfFile:htmlPath 
                                               encoding:NSUTF8StringEncoding 
                                                  error:nil];

    [webView loadHTMLString:html 
                    baseURL:[NSURL fileURLWithPath:
                             [NSString stringWithFormat:@"%@/htdocs/", 
                             [[NSBundle mainBundle] bundlePath]]]];
}

And this should be the results:

enter image description here enter image description here

EDIT:

snowman4415 mentioned that iOS 7 does not like self closing tags script tags, so if something is not working on iOS 7, you may need to close the tag with </script>