如何从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,将您想要传递给您的应用的信息进行编码,例如:

 window.location = "fake://myApp/something_happened:param1:param2:param3"; 

在您的委托方法中,查找这些伪造的URL,提取所需的信息,采取适当的操作,并返回NO以取消导航。 这可能是最好的,如果你推迟使用某些performSelector味道冗长的处理。

不build议使用JS调用objective-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中执行,所以在快速调用时不应忽略它们。

感谢这个家伙 。

Obliviux,

你的代码似乎是完美的。

问题的原因是,你一定错过了映射委托。

  1. 将webView的委托连接到.xib文件中的文件所有者

要么

  1. 使用webView.delegate = self;

在你的viewDidLoad

谢谢

就像人们在这里所说的,你必须使用UIWebviewDelegate的方法webView:shouldStartLoadWithRequest:navigationType:。

这个API http://code.google.com/p/jsbridge-to-cocoa/为你做。; 这是非常轻量级的。 您可以将图像,string和数组从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之间来回通信的库。 还有其他的库和解决scheme。

如果你正在谈论一个Web应用程序(用户从Mobile Safari获得的东西),那么你不能从那里进入Objective-C。

检查这一个 – 了解使用这个(或其他JavaScript)函数的XMLHttpRequest响应? ,它使用目标C来调用Ajax js函数,并在完成后得到响应,你知道的诀窍是,当你改变位置在JavaScript中触发webview,所以你可以检查位置知道它的JavaScript调用或真正的要求。