在iOS中,如何从中的Javascript调用Objective-C方法UIWebView并将其发送回Java数据?我知道可以使用Webkit库在OSX上完成此操作,但是在iOS上可以吗?PhoneGap如何实现这一目标?
UIWebView
有一个API可直接从Objective-C调用JavaScript, 但不能直接从Javascript调用Objective-C。
您必须将Javascript操作序列化为一个特殊的URL,并在UIWebView的委托shouldStartLoadWithRequest方法中截取该URL 。
shouldStartLoadWithRequest
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
在这里,您可以反序列化该特殊URL并对其进行解释,以实现Objective- C方面的目标。(您应该返回NO上述shouldStartLoadWithRequest方法,以便UIWebView不会使用您的虚假URL实际发出HTTP请求来加载网页。)
NO
然后,您可以通过在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的片段位于后面#。)
UIWebView.delegate
#
- (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; }