javascript - iOS 从 Javascript 调用 Objective-C : Some calls are ignored?

标签 javascript objective-c ios timing

我已经使用 UIWebView 委托(delegate) shouldStartLoadWithRequest() 方法在 iOS 上实现了似乎是从 javascript 到 objective-c 通信的唯一方法。

起初似乎工作正常,但现在我注意到,如果我在短时间内多次从 javascript 调用 objective-c,第二次调用通常会被忽略(该应用程序是钢琴键盘,每次按键触发对 native 代码的调用,当处理多个触摸时, native 代码不会为每个手指都调用)。

这是我响应 javascript 调用的 objective-c 代码。我知道这很愚蠢,但我只是想要一些暂时可用的东西。

- (BOOL)webView:(UIWebView *)webView2 shouldStartLoadWithRequest:(NSURLRequest *)request 
        navigationType:(UIWebViewNavigationType)navigationType 
{  
  // Intercept custom location change, URL begins with "js-call:"
  NSString * requestString = [[request URL] absoluteString];
  if ([requestString hasPrefix:@"js-call:"]) 
  {
    // Extract the selector name from the URL
    NSArray * components = [requestString componentsSeparatedByString:@":"];
    NSString * functionCall = [components objectAtIndex:1];
    NSArray * params = [functionCall componentsSeparatedByString:@"%20"];
    NSString * functionName = [params objectAtIndex:0];

    // Parse playnote event
    if ([functionName isEqualToString:@"playNote"])
    {
      NSString * param = [params objectAtIndex:1];
      NoteInstanceID note_id = [m_audioController playNote:[param intValue]];
      NSString * jscall = [NSString stringWithFormat:@"document.PlayNoteCallback(%i);", note_id];
      NSLog(@"playNote: %i", (int)note_id);
      [m_webView stringByEvaluatingJavaScriptFromString:jscall];
    }

    // Parse stopnote event
    if ([functionName isEqualToString:@"stopNote"])
    {
      NSString * param = [params objectAtIndex:1];
      NoteInstanceID note_id = [param intValue];
      NSLog(@"stopNote: %i", (int)note_id); 
      [m_audioController stopNote:note_id];
    }

    // Parse log event
    if ([functionName isEqualToString:@"debugLog"])
    {
      NSString * str = [requestString stringByReplacingOccurrencesOfString:@"%20" withString:@" "];
      NSLog(@"%s", [str cStringUsingEncoding:NSStringEncodingConversionAllowLossy]);
    }

    // Cancel the location change
    return NO;
  }

  // Accept this location change
  return YES;

}

在 javascript 中,我通过设置单个隐藏 iframe 的 src 属性来调用 objective-c 方法。这将触发 objective-c 中的委托(delegate)方法,然后将调用所需的 native 代码。

$("#app_handle").attr("src", "js-call:playNote " + key.data("pitch"));

app_handle 是相关 iframe 的 ID。

综上所述,我的方法基本可以,但是短时间内多次调用不行。这只是我们被迫从 javascript 到 objective-c 的可怕方法的产物吗?还是我做错了什么?我知道 PhoneGap 做了类似的事情来实现相同的目标。我宁愿不使用 PhoneGap,所以如果他们没有这个问题,那么我很想弄清楚他们正在做什么来使这项工作成功。

更新:

我刚找到这个:send a notification from javascript in UIWebView to ObjectiveC 这证实了我对快速连续调用的电话丢失的怀疑。显然,我需要将我的调用集中在一起或手动延迟调用,以便在我再次调用电话时返回 url 请求。

最佳答案

接受的答案没有解决问题,因为在第一个处理之前到达的位置更改仍然被忽略。查看第一条评论。

我建议采用以下方法:

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 .

关于javascript - iOS 从 Javascript 调用 Objective-C : Some calls are ignored?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10609228/

相关文章:

objective-c - 如何将 JSON 字符串转换为 NSArray?

ios - 加载 View 时未调用方法

ios - 使用 UISplitViewController 而不是仅创建具有 2 个 subview 的单个 UIViewController 有什么好处

JavaScript,没有 JQuery 请问,如何获取 iframe 中特定标签的总数

javascript - 延迟加载不会在 Angular 中创建 chunk.js

Javascript 验证函数未执行

iphone - 添加授权文件

ios - 如何用新数据刷新 UItableViewcell

ios - UIView 的 getter 和 setter

javascript - 函数的定义与顺序无关吗?