使用 windowScriptObject 和 WebKit 通过 JavaScript 调用 MacRuby

发布于 2024-10-20 19:26:55 字数 2387 浏览 4 评论 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] 的结果不是函数

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

任何帮助将不胜感激。

I have a new MacRuby application. I'm trying to call a MacRuby method from JavaScript loaded in a webView within the application.

The Calling Objective-C Methods From JavaScript tutorial shows how to add a key to the webScriptObject that's value is an Objective-C object. Thus you can call Obj-C methods from JavaScript.

Unfortunately this does not work with MacRuby classes/methods. Below is a shorten version of my WebView's 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

When the webScriptObject is available i add two keys to it: ObjCInstance and MacRubyInstance.

Here's the implementation of the ObjC class:

#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

And here's what's supposed to be the same thing in 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

The only problem is the Objective-C implementation works fine. On the JS side you can call:

window.ObjCInstance.nameAtIndex_(1) 

Which returns the string "works".

But the MacRuby implementation fails. When you call:

window.MacRubyInstance.nameAtIndex_(1) 

You get:

Result of expression 'window.MacRubyInstance.nameAtIndex_' [undefined] is not a function

The webScriptNameForSelector and isSelectorExcludedFromWebScript methods never get called on the MacRuby implementation. I think that's the problem, but I don't know why they aren't getting called.

Any help would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

·深蓝 2024-10-27 19:26:55

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

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

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

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

def self.isSelectorExcludedFromWebScript(sel); false end

另外,希望我的示例能够帮助您解决这个问题。

I showed how to do that in this tutorial/blog post.

My guess is that in your case, the following code is the problem:

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

The selector sent as an argument is more than likely not equal to the symbol your put. Try to return false for all and see if that works. Try:

def self.isSelectorExcludedFromWebScript(sel); false end

Also, hopefully my example will help you fix this issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文