开发者

Is it possible to use JavaScript in Objective-C (iphone)?

If possible, then ho开发者_运维技巧w can I use JavaScript in my code?


It is possible to inject JavaScript in a UIWebView.

NSString * result = [myUIWebView stringByEvaluatingJavaScriptFromString:@"document.getElementById('foo').className"];


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.

On the Javascript side:

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::";
}

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:

@interface MyWebViewController : UIViewController <UIWebViewDelegate>{
  //declare stuff
}

On the implementation side, somewhere:

[(UIWebView *)self.view setDelegate:self];

You then catch the request by implementing the following:

- (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"])&&([segments count] > 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"])&&([segments count] > 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
  }
}

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.

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜