Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>To add to j_freyre's answer, which shows you how to execute and get data out of Javascript from Objective C, you can also call Objective C code from Javascript running in a UIWebView. This requires a little bit more work, and is a little hackish.</p> <p>On the Javascript side:</p> <pre><code>var call_stack = new Array(); //This will hold our Objective C function calls function addWithObjC(a,b){ call_stack.splice(0,0,"add:"+a+":"+b); //We separate the components of the call (function name, parameters) by a colon, but it could be anything. window.location.href = "::ObjCcall::"; } function multiplyWithObjC(a,b){ call_stack.splice(0,0,"multiply:"+a+":"+b); window.location.href = "::ObjCcall::"; } </code></pre> <p>This will attempt to load a bogus url. "::ObjCcall::" could be anything that's not a potentially valid url. The trick is now to catch this request in Objective C. Assuming you have a UIWebView and a corresponding UIViewController, in your UIViewController interface specify:</p> <pre><code>@interface MyWebViewController : UIViewController &lt;UIWebViewDelegate&gt;{ //declare stuff } </code></pre> <p>On the implementation side, somewhere:</p> <pre><code>[(UIWebView *)self.view setDelegate:self]; </code></pre> <p>You then catch the request by implementing the following:</p> <pre><code>- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSString *url = [[request URL] absoluteString]; //Our potentially bogus request url if([url hasSuffix:@"::ObjCcall::"]){ //We're trying to call Objective C code NSString *command; //Our specially formatted function call //While our call stack is not empty... while(![command = [webView stringByEvaluatingJavaScriptFromString:@"call_stack.pop()"]isEqualToString:@""]){ //Break the function call into its compoments NSArray *segments = [command componentsSeparatedByString:@":"]; //We found a call we respond to if(([[segments objectAtIndex:0] isEqualToString:@"add"])&amp;&amp;([segments count] &gt; 2)){ //Here is where the Objective C action takes place float result = [[segments objectAtIndex:1]floatValue] + [[segments objectAtIndex:2]floatValue]; //Do something with the results... } else if(([[segments objectAtIndex:0] isEqualToString:@"multiply"])&amp;&amp;([segments count] &gt; 2)){ //Another function float result = [[segments objectAtIndex:1]floatValue] * [[segments objectAtIndex:2]floatValue]; } //Add more checks as needed [segments release]; return NO; //This tells the UIWebView to not try to load the page } } else{ return YES; //This is a valid URL request, load the page } } </code></pre> <p>This is a little bit more complicated than it might seem necessary. However, the UIWebView doesn't like window.location.href being changed in rapid succession. We implement a call stack to be sure that no call gets skipped by. </p> <p>It's a lot more work to setup than call Javascript from Objective C, for sure, but once you've setup the boilerplate, all you need to do is add checks in the while loop inside shouldStartLoadWithRequest.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload