0

我有一个新的 MacRuby 应用程序。我正在尝试从应用程序的 webView 中加载的 JavaScript 调用 MacRuby 方法。

JavaScript 调用 Objective-C 方法教程展示了如何向 webScriptObject 添加一个键,该键的值是一个 Objective-C 对象。因此,您可以从 JavaScript 调用 Obj-C 方法。

不幸的是,这不适用于 MacRuby 类/方法。下面是我的 WebView 的 loadDelegate 的简化版本:

class WebLoadDelegate

attr_accessor :objc_bridge, :mr_bridge

def webView(sender, windowScriptObjectAvailable:windowScriptObject)
    scriptObject = windowScriptObject

    self.mr_bridge = MacRubyBridge.new();
    self.objc_bridge = JavaScriptBridge.instance();

    scriptObject.setValue(self.objc_bridge, forKey:"ObjCInstance")
    scriptObject.setValue(self.mr_bridge, forKey:"MacRubyInstance")
end

end

当 webScriptObject 可用时,我向它添加两个键:ObjCInstance 和 MacRubyInstance。

下面是 ObjC 类的实现:

#import "JavaScriptBridge.h"

static JavaScriptBridge *gInstance = NULL;

@implementation JavaScriptBridge

+ (JavaScriptBridge *)instance {
    gInstance = [[self alloc] init];

    return gInstance;
}

+ (NSString *) webScriptNameForSelector:(SEL)sel
{       
    return @"nameAtIndex";
}

+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
    if (aSelector == @selector(nameAtIndex:)) return NO;
    return YES;
}

- (NSString *)nameAtIndex:(int)index {
    return @"works";
}


@end

这就是 Ruby 中应该是相同的东西:

class MacRubyBridge

    def nameAtIndex(i)
        return "fails"
    end

    def self.webScriptNameForSelector(sel)
        return "nameAtIndex";
    end


    def self.isSelectorExcludedFromWebScript(sel)
        if (sel == :nameAtIndex) 
            false
        else
            true
        end
    end

end

唯一的问题是 Objective-C 实现工作正常。在 JS 方面,您可以调用:

window.ObjCInstance.nameAtIndex_(1) 

它返回字符串“works”。

但是 MacRuby 的实现失败了。你打电话时:

window.MacRubyInstance.nameAtIndex_(1) 

你得到:

表达式 'window.MacRubyInstance.nameAtIndex_' [undefined] 的结果不是函数

和方法永远不会在 MacRuby 实现上被调用webScriptNameForSelectorisSelectorExcludedFromWebScript我认为这就是问题所在,但我不知道为什么他们没有接到电话。

任何帮助将不胜感激。

4

1 回答 1

2

我在本教程/博客文章中展示了如何做到这一点。

我的猜测是,在您的情况下,以下代码是问题所在:

    def self.isSelectorExcludedFromWebScript(sel)
     if (sel == :nameAtIndex) 
         false
     else
        true
     end
   end

作为参数发送的选择器很可能不等于您放置的符号。尝试为所有人返回 false ,看看是否有效。尝试:

def self.isSelectorExcludedFromWebScript(sel); false end

另外,希望我的示例可以帮助您解决此问题。

于 2011-03-21T05:33:02.213 回答