有一个API直接从Objective-C调用JavaScript,但你不能直接从Javascript调用Objective-C。
如何告诉您的Objective-C代码从WebView中的Javascript执行某些操作
您必须将Javascript操作序列化为特殊URL,并在UIWebView的委托shouldStartLoadWithRequest方法中拦截该URL 。
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType;
在那里,您可以反序列化该特殊URL并将其解释为在Objective-C端执行您想要的操作。(您应该NO在上面的shouldStartLoadWithRequest方法中返回,以便UIWebView不会使用您的虚假URL来实际发出加载网页的HTTP请求。)
如何从Objective-C运行Javascript代码
然后,您可以通过在webview上调用此方法从Objective-C运行Javascript。
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
示例代码
我建议使用伪造的URL方案,以便很容易区分您的操作URL和合法请求。您可以在Javascript中按以下方式提出此请求:
// JavaScript to send an action to your Objective-C code
var myAppName = 'myfakeappname';
var myActionType = 'myJavascriptActionType';
var myActionParameters = {}; // put extra info into a dict if you need it
// (separating the actionType from parameters makes it easier to parse in ObjC.)
var jsonString = (JSON.stringify(myActionParameters));
var escapedJsonParameters = escape(jsonString);
var url = myAppName + '://' + myActionType + "#" + escapedJsonParameters;
document.location.href = url;
然后在UIWebView.delegate的shouldStartLoadWithRequest方法,你可以检查URL方案和片段,以检查它是否是一个正常的请求或你的特别行动之一。(URL的片段是之后的#。)
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
// these need to match the values defined in your JavaScript
NSString *myAppScheme = @"myfakeappname";
NSString *myActionType = @"myJavascriptActionType";
// ignore legit webview requests so they load normally
if (![request.URL.scheme isEqualToString:myAppScheme]) {
return YES;
}
// get the action from the path
NSString *actionType = request.URL.host;
// deserialize the request JSON
NSString *jsonDictString = [request.URL.fragment stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
// look at the actionType and do whatever you want here
if ([actionType isEqualToString:myActionType]) {
// do something in response to your javascript action
// if you used an action parameters dict, deserialize and inspect it here
}
// make sure to return NO so that your webview doesn't try to load your made-up URL
return NO;
}