如何从Javascript调用Objective C方法并将数据发送回iOS中的Javascript? [英] How to invoke Objective C method from Javascript and send back data to Javascript in iOS?
问题描述
在iOS中,如何在 UIWebView
中从Javascript调用Objective-C方法并让它将数据发送回Javascript?我知道这可以使用Webkit库在OS X上完成,但是这可以在iOS上实现吗? PhoneGap如何实现这一目标?
In iOS, how can I call an Objective-C method from Javascript in a UIWebView
and have it send data back to the Javascript? I know that this could be done on OS X using the Webkit library, but is this possible on iOS? How does PhoneGap achieve this?
推荐答案
有一个API直接从Objective-C调用JavaScript,但你不能直接从Javascript调用Objective-C。
There is an API to call JavaScript directly from Objective-C, but you cannot call Objective-C directly from Javascript.
您必须将Javascript操作序列化为特殊URL,并在UIWebView的委托的 shouldStartLoadWithRequest
方法中拦截该URL。
You have to serialize your Javascript action into a special URL and intercept that URL in the UIWebView's delegate's shouldStartLoadWithRequest
method.
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType;
在那里,您可以反序列化该特殊URL并将其解释为在Objective-C端执行您想要的操作。 (您应该在上面的 shouldStartLoadWithRequest
方法中返回 NO
,这样UIWebView就不会使用您的虚假URL来实际制作用于加载网页的HTTP请求。)
There you can deserialize that special URL and interpret it to do what you want on the Objective-C side. (You should return NO
in the above shouldStartLoadWithRequest
method so the UIWebView doesn't use your bogus URL to actually make an HTTP request to load a webpage.)
然后你可以通过在webview上调用此方法从Objective-C运行Javascript。
Then you can run Javascript from Objective-C by calling this method on your webview.
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
示例代码
我建议使用虚假URL方案,因此很容易区分您的操作URL和合法请求。您可以在Javascript中按以下方式提出此请求:
Example Code
I recommend using a bogus URL scheme so it will be easy to tell the difference between your action URLs and legit requests. You can make this request in the Javascript along these lines:
// 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的片段是#
之后的内容。)
Then in the UIWebView.delegate
's shouldStartLoadWithRequest
method, you can inspect the URL scheme and fragment to check if it's a normal request or one of your special actions. (The fragment of a URL is what comes after the #
.)
- (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;
}
(阅读这个答案如果您需要帮助将您的json字符串反序列化为NSDictionary。)
(Read this answer if you need help deserializing your json string into an NSDictionary.)
这篇关于如何从Javascript调用Objective C方法并将数据发送回iOS中的Javascript?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!