Logan Serman
Logan Serman

Reputation: 29870

"Inject" Objective-C data into a UIWebView that loads a local HTML file?

I am trying to load a UIWebView with local HTML/CSS that is build to look like a nutrition label. The problem is, the data for the food lies inside of my iPhone app. Do I have to put all of my HTML into one enormous NSString object and concatenate my data into it, or is there a way to load the HTML from a local .html file, but somehow "inject" the data that is stored within Objective-C into it?

Upvotes: 0

Views: 1947

Answers (4)

Pierre
Pierre

Reputation: 400

Since iOS 2 you can use - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script within a UIWebView subclass to execute JS scripts in your webview. This is the best way to inject data from the "Objective-C part" of your application.

Cf: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIWebView_Class/#//apple_ref/occ/instm/UIWebView/stringByEvaluatingJavaScriptFromString:

Upvotes: 0

joerick
joerick

Reputation: 16448

I would do a hybrid of both- have an HTML file in the app that you load, then replace certain strings in that before giving it to the UIWebView. So for example, you could have a file like this

<html>
<head>
<title><!--foodName--></title>
</head>
<body>
<h1><!--foodName--></h1>
<p>Calories / 100g: <!--foodCalories--></p>
</body>
</html>

You'd load that into Cocoa, then replace your special placeholder comments with the actual values you want.

NSDictionary *substitutions = [NSDictionary dictionaryWithObjectsAndKeys: 
                               @"Carrots", @"foodName",
                               [NSNumber numberWithInt:20], @"foodCalories",
                               // add more as needed
                               nil];

NSMutableString *html = [NSMutableString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"foodCard" ofType:@"html"] 
                                                         encoding:NSUTF8StringEncoding
                                                            error:nil];

for(NSString *substitutionKey in substitutions)
{
    NSString *substitution = [[substitution objectForKey:substitutionKey] description];
    NSString *searchTerm = [NSString stringWithFormat:@"<!--%@-->", substitutionKey];

    [html replaceOccurrencesOfString:searchTerm withString:substitution options:0 range:NSMakeRange(0, [html length])];
}

[webView loadHTMLString:html baseURL:[[NSBundle mainBundle] resourceURL]];

Upvotes: 0

matt
matt

Reputation: 534925

If the data to be injected is "safe", you could construct your "enormous NSString object" as a format string, sprinkled with %@ markers, and use stringWithFormat: to perform the injection in a single move. This is how I construct the pages in the TidBITS News app, using pieces that all come from RSS. It's really quite painless.

Upvotes: 2

pawlowski
pawlowski

Reputation: 123

You can load basic html using NSData's method dataWithContentsOfFile and then use javascript to modify html in the way you need.

Code would look something like this (using this example):

NSString *path = [[NSBundle mainBundle] pathForResource:@"food" ofType:@"html"]; 
NSData *data = [NSData dataWithContentsOfFile:path];
if (data) {  
    [webView loadData:data MIMEType:@"text/html" textEncodingName:@"UTF-8"];  
}
[webView stringByEvaluatingJavaScriptFromString:@"var script = document.createElement('script');"
                     "script.type = 'text/javascript';"
                     "script.text = \"function myFunction() { "
                        "var field = document.getElementById('field_3');"
                        "field.value='Calling function - OK';"
                     "}\";"
                     "document.getElementsByTagName('head')[0].appendChild(script);"];

[webView stringByEvaluatingJavaScriptFromString:@"myFunction();"];

Upvotes: 1

Related Questions