如何从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,
你的代码似乎是完美的。
问题的原因是,你一定错过了映射委托。
或
- 将webView的委托连接到.xib文件中的文件所有者
要么
- 使用
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调用或真正的要求。