Iphone 如何从Javascript调用Objective-C?
我有一个WebView,我想从JavaScript调用Objective-C中的一个视图。有人知道我怎么做吗Iphone 如何从Javascript调用Objective-C?,iphone,cocoa-touch,uiwebview,Iphone,Cocoa Touch,Uiwebview,我有一个WebView,我想从JavaScript调用Objective-C中的一个视图。有人知道我怎么做吗 我的ViewController中有以下代码: - (BOOL)webView:(UIWebView *)webView2 shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSString *requestS
我的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.
}
但是什么也没发生。假设你在做一个应用程序,你可以看看如何实现它(甚至使用它)。它是一个支持JS和OBJ-C之间来回通信的库。还有其他库和解决方案
如果您谈论的是一个web应用程序(用户从Mobile Safari获得的东西),那么您无法从那里获得Objective-C。UIWebView的标准解决方法是设置一个
UIWebViewDelegate
,并实现该方法。在JavaScript代码中,导航到某个伪造的URL,该URL对要传递给应用程序的信息进行编码,例如:
window.location = "fake://myApp/something_happened:param1:param2:param3";
在委托方法中,查找这些假URL,提取所需信息,采取任何适当的操作,然后返回
NO
以取消导航。最好是使用延迟任何长时间的处理。正如人们在这里所说的,您必须使用UIWebviewDelegate中的webView:shouldStartLoadWithRequest:navigationType:方法
这个api为您实现了这一点。它很轻。您可以将图像、字符串和数组从javascript传递到objective-C。Obliviux
你的代码似乎很完美
出现此问题的原因是您一定错过了映射代理
或者
webView.delegate=self代码>
视图中加载
感谢检查这个-,它使用objective C调用ajax js函数,并在完成后得到响应,你知道诀窍是当你在javascript中更改位置时会触发webview,因此,您可以查看位置以了解您的javascript调用或实际请求。我对这种方法有一个问题:我想向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()。这种方法对我很有效,也许能帮助有同样问题的人 不推荐从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中执行,因此在快速调用时不应忽略它们
归功于。尽管这是一个非常古老的问题,但谷歌一直在回答它,现在有一个很好的答案:WebScripting非正式协议。它允许您向Javascript公开一个目标C对象
此解决方案的问题是,如果“fake/…”加载失败,则不会调用webview:shouldStartLoadWithRequest:navigationType:。有什么方法可以修复它吗?在调用webview:shouldStartLoadWithRequest:navigationType:
之前,什么会导致它失败?(这个回调的要点是,它发生在系统开始任何网络加载之前,等等)我建议,它使事情变得更加灵活。您可以通过cordova.exec(function(success){alert('success');console.log(success);},function(fail)从js调用本机方法{console.log(fail);},,'',[]);并将这一行添加到config.xml关于这个问题的任何内容都不会假定应用程序正在使用Cordova,但是如果您使用Cordova,并且他们为此提供了一个帮助函数,那么这就很方便了。如果您只是使用setTimeout
异步设置窗口位置,那么它就不起作用了。如果window.location没有被处理,那么您仍然会遇到问题如果它掉了那个“位置”。看我的答案,它似乎在没有轮询或估计延迟的情况下解决了这个问题。。setTimeout解决方案不是很优雅:)请不要这样做。请听@talkol。您尝试过这个URL吗?这里可能重复了Sixten Otto的详细回复示例:您可能必须编辑您的答案,因为无法从ja发送图像vascript到objective c。您所展示的示例只是通过window.location方式将图像的id从javascript传递到objective c。此外,图像位于本地主捆绑包中。为什么我们要在最后一行将null
分配给iframe