如何从Javascript调用Objective-C?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从Javascript调用Objective-C?相关的知识,希望对你有一定的参考价值。
我有一个WebView,我想从javascript调用Objective-C中的一个视图。有人知道我怎么做吗?
我的ViewController中有这个代码:
- (BOOL)webView:(UIWebView *)webView2
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSString *requestString = [[request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:@":"];
if ([components count] > 1 &&
[(NSString *)[components objectAtIndex:0] isEqualToString:@"myapp"]) {
if([(NSString *)[components objectAtIndex:1] isEqualToString:@"myfunction"])
{
NSLog([components objectAtIndex:2]); [[Airship shared] displayStoreFront]; //<- This is the code to open the Store
NSLog([components objectAtIndex:3]); // param2
// Call your method in Objective-C method using the above...
}
return NO;
}
return YES; // Return YES to make sure regular navigation works as expected.
}
并在Javascript中:
function store(event)
{
document.location = "myapp:" + "myfunction:" + param1 + ":" + param2;
}
但没有任何反应。
UIWebView
的标准解决方法是设置UIWebViewDelegate
,并实现方法webView:shouldStartLoadWithRequest:navigationType:
。在您的JavaScript代码中,导航到一些伪造的URL,该URL会对您要传递给应用的信息进行编码,例如:
window.location = "fake://myApp/something_happened:param1:param2:param3";
在您的委托方法中,查找这些虚假URL,提取您需要的信息,采取适当的操作,并返回NO
以取消导航。如果你推迟使用some flavor of performSelector
进行任何冗长的处理,这可能是最好的。
不建议从JS调用目标c的window.location方法。问题的一个例子:如果你进行两次立即连续调用,则忽略一次(因为你不能太快地改变位置) - 自己尝试一下..
我推荐以下替代方法:
function execute(url)
{
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", url);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
你反复调用execute
函数,因为每个调用都在自己的iframe中执行,所以在快速调用时不应忽略它们。
积分兑换this guy。
Obliviux,
你的代码似乎很完美。
问题的原因是你必须错过映射代表。
或
- 将webView的委托连接到.xib文件中的文件所有者
要么
- 使用
webView.delegate = self;
在你的viewDidLoad
。
谢谢
就像人们在这里所说的那样,你必须使用webView:shouldStartLoadWithRequest:navigationType:来自UIWebviewDelegate。
这个api http://code.google.com/p/jsbridge-to-cocoa/为你做。它非常轻巧。您可以将图像,字符串和数组从javascript传递到objective-C。
我对这种方法有一个问题:我想向iphone设备发送几条消息,但似乎它们被“重叠”,因为它们无法顺序处理所有这些消息。
示例:执行此代码时:
window.location = "app://action/foo";
window.location = "app://action/bar";
行动foo
从未被执行过。
我必须做的是以下内容:
waitingForMessage = false;
function MsgProcessed(){
waitingForMessage = false;
}
function SyncLaunchURL(url){
if (waitingForMessage){
setTimeout(function(){SyncLaunchURL(url)},100);
}else{
window.location = url
waitingForMessage = true;
}
}
SyncLaunchURL("app://action/foo");
SyncLaunchURL("app://action/bar");
使用这种方法,iphone必须在处理呼叫后调用MsgProcessed()。这种方式适合我,也许可以帮助有同样问题的人!
假设你正在做一个应用程序,你可以看看PhoneGap如何实现它(甚至使用它)。它是一个支持JS和OBJ-C之间来回通信的库。还有其他库和解决方案。
如果您正在谈论一个Web应用程序(用户从Mobile Safari获得的东西),那么您无法从那里获得Objective-C。
检查一下 - understanding XMLHttpRequest responses using this (or other javascript) functions?,它使用目标C调用ajax js函数,并在完成后得到响应,你知道诀窍是当你在javascript中更改位置时会触发webview,所以你可以检查位置知道它是您的JavaScript调用或真实请求。
虽然现在这是一个非常古老的问题,但谷歌一直在回归,现在有一个很好的答案:WebScripting非正式协议。它允许您将目标C对象公开给Javascript。
以上是关于如何从Javascript调用Objective-C?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Objective-C 中调用的 JavaScript 函数访问 response.body?
如何使用单个参数从 Javascript 调用 Objective-C 方法并在 Xcode 中处理它
从 Javascript 调用 Objective-C 方法
通过 Cordova 插件从 Objective-C 调用 Javascript