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.
精彩评论