Iphone 如何从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

我有一个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.
}

但是什么也没发生。

假设你在做一个应用程序,你可以看看如何实现它(甚至使用它)。它是一个支持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的委托连接到.xib文件中的文件所有者
  • 使用
    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