【问题标题】:How to call an Objective-C method from Javascript in a Cocoa/WebKit app?如何在 Cocoa/WebKit 应用程序中从 Javascript 调用 Objective-C 方法?
【发布时间】:2008-09-18 13:21:33
【问题描述】:

我有一个使用 WebView 来显示 HTML 界面的 Cocoa 应用程序。我将如何从 HTML 界面中的 Javascript 函数调用 Objective-C 方法?

【问题讨论】:

    标签: javascript objective-c cocoa webkit


    【解决方案1】:

    这记录在developer.apple.com

    【讨论】:

    【解决方案2】:

    Apple 的文档比较环保,对我来说几乎无法使用,所以我做了一个概念证明,即在 Cocoa 中从 javascript 调用 Objective C 方法,反之亦然,尽管后者更容易。

    首先确保您的 webview 作为 setFrameLoadDelegate:

    [testWinWebView setFrameLoadDelegate:self];
    

    您需要告诉 webview 在加载后立即监视特定对象:

    - (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowScriptObject forFrame:(WebFrame *)frame {
        //add the controller to the script environment
        //the "ObjCConnector" object will now be available to JavaScript
        [windowScriptObject setValue:self forKey:@"ObjCConnector"];
    }
    

    然后是通讯的业务:

    // a few methods to log activity
    - (void)acceptJavaScriptFunctionOne:(NSString*) logText {
        NSLog(@"acceptJavaScriptFunctionOne: %@",logText);
    }
    - (void)acceptJavaScriptFunctionTwo:(NSString*) logText {
        NSLog(@"acceptJavaScriptFunctionTwo: %@",logText);
    }
    
    //this returns a nice name for the method in the JavaScript environment
    +(NSString*)webScriptNameForSelector:(SEL)sel {
        NSLog(@"%@ received %@ with sel='%@'", self, NSStringFromSelector(_cmd), NSStringFromSelector(sel));
        if(sel == @selector(acceptJavaScriptFunctionOne:))
            return @"functionOne"; // this is what you're sending in from JS to map to above line
        if(sel == @selector(acceptJavaScriptFunctionTwo:))
            return @"functionTwo"; // this is what you're sending in from JS to map to above line
        return nil;
    }
    
    //this allows JavaScript to call the -logJavaScriptString: method
    + (BOOL)isSelectorExcludedFromWebScript:(SEL)sel {
        NSLog(@"isSelectorExcludedFromWebScript: %@", NSStringFromSelector(sel));
        if(sel == @selector(acceptJavaScriptFunctionOne:) ||
           sel == @selector(acceptJavaScriptFunctionTwo:))
            return NO;
        return YES;
    }
    

    关键是,如果您有多个要调用的方法,则需要将它们全部排除在 isSelectorExcludedFromWebScript 方法中,并且需要通过 javascript 调用映射到 webScriptNameForSelector 中的 ObjC 方法。

    完整的项目概念证明文件: https://github.com/bytestudios/JS-function-and-ObjC-method-connector

    【讨论】:

    • 感谢您提供有用的信息。这个答案对我帮助很大!!
    【解决方案3】:

    如果您想在 iPhone 应用程序中执行此操作,则需要使用 UIWebViewDelegate 方法 shouldStartLoadWithRequest:

    这个 api http://code.google.com/p/jsbridge-to-cocoa/ 为你做。它非常轻巧。

    【讨论】:

      【解决方案4】:

      我有一个使用 NimbleKit 的解决方案。它可以从 Javascript 调用 Objective C 函数。

      【讨论】:

      • 对你有多好,分享一下如何?
      猜你喜欢
      • 2012-04-29
      • 1970-01-01
      • 2011-02-13
      • 2011-05-10
      • 1970-01-01
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多