使用 windowScriptObject 和 WebKit 通过 JavaScript 调用 MacRuby
我有一个新的 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] 的结果不是函数
webScriptNameForSelector
和 isSelectorExcludedFromWebScript
方法永远不会被调用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我在本教程/博客文章中展示了如何做到这一点。
我的猜测是,在您的情况下,以下代码是问题所在:
作为参数发送的选择器很可能不等于您放置的符号。尝试对所有内容返回 false 并查看是否有效。尝试:
另外,希望我的示例能够帮助您解决这个问题。
I showed how to do that in this tutorial/blog post.
My guess is that in your case, the following code is the problem:
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:
Also, hopefully my example will help you fix this issue.