如何从Javascript调用Objective C方法并在iOS中将数据发送回Javascript?
在iOS中,如何从UIWebView
Javascript中调用Objective-C方法,并将数据发送回Javascript? 我知道这可以使用Webkit库在OS X上完成,但在iOS上可以吗? PhoneGap如何实现这一目标?
有一个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上做你想做的事情。 (您应该在上面的shouldStartLoadWithRequest
方法中返回NO
,以便UIWebView不会使用您的伪造URL实际发出HTTP请求来加载网页。)
如何从Objective-C运行Javascript代码
然后你可以通过在你的webview中调用这个方法来从Objective-C运行Javascript。
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
示例代码
我build议使用伪造的URLscheme,这样就很容易区分你的动作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
方法中,可以检查URLscheme和片段,以检查它是一个正常请求还是您的特殊操作之一。 (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; }
(阅读这个答案,如果你需要帮助反序列化您的JSONstring到NSDictionary。)
更改页面的位置可能会导致几个问题 :
- 所有setInterval和setTimeout立即停止位置更改
- 每个innerHTML在取消位置更改后都不起作用!
- 你可能会得到其他很奇怪的错误,真的很难诊断…
这里提供的解决scheme是:
继续使用相同的URL技术(在js和objective-c上),只需使用iframe更改位置:
var iframe = document.createElement("IFRAME"); iframe.setAttribute("src", "js-frame:myObjectiveCFunction"; document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null;
希望有所帮助
从Objective-C:你可以将一个string的JavaScript函数传递给UIWebView。 网页将执行它并返回结果。 这样你可以传递variables并从Javascript获取数据。
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script
例:
NSString *script = @"document.getElementById('myTextField').value"; NSString *output = [myWebView stringByEvaluatingJavaScriptFromString:script];
来自Javascript:将您的数据传递到URL中。 在UIWebViewDelegate中拦截URL请求。 通过返回NO获取数据并终止URL请求。
<script>window.location = "url://key1/value1"; </script>
拦截URL请求
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
- 是需要ARC中的NSNotificationCenter removeObserver?
- UITapGestureRecognizerselect器,发件人是手势,而不是ui对象
- 我可以在UIScrollView中使用UIRefreshControl吗?
- 如何找出用于构build* .ipa文件的configuration文件?
- LaunchScreen.xib不显示我的自定义字体
- 如何从iTunes Connect中删除tvOS应用程序?
- GCD,线程,程序stream和UI更新
- 使用AVAsset制作带有图片arrays和歌曲文件的电影文件
- 是否有可能使用Python来为iOS和Android编写跨平台的应用程序?