我正在使用a WebScriptObject
在Objective-C(OS X)的WebView中调用JavaScript方法。我想发送和接收像数组和字典这样的对象。
我可以这样收到:
// JWJSBridge
+ (BOOL)isSelectorExpludedFromWebScript:(SEL)selector {
if (selector == @selector(log:)) {
return NO;
}
return YES;
}
+ (NSString *)webScriptNameForSelector:(SEL)selector {
if (selector == @selector(log:)) {
return @"log";
}
return nil;
}
- (void)log:(WebScriptObject *)object {
NSLog(@"object: %@", [[object JSValue] toObject]);
}
此对象设置为JavaScript环境,如下所示:
WebScriptObject *windowObject = [[self webView] windowScriptObject];
[windowObject setValue:[[JWJSBridge alloc] init] forKey:@"external"];
然后,当我按window.external.log({key: "value"});
进行JavaScript调用时,JWJSBridge
将对象记录为NSDictionary
。
现在我也想以另一种方式实现它。为此我创建了一个像这样的JavaScript对象:
window.internal = {log = function(a) { console.log(a); }};
它与数组完美配合:
WebScriptObject *internal = [[self webView] valueForKey:@"internal"];
[internal callWebScriptMethod:@"log" withArguments:@[@[@"value", @"value"]]];
但是当我想发送字典时,这是不可能的:
[internal callWebScriptMethod:@"log" withArgument:@[@{@"key": @"value"}]];
知道我很遗憾地得到一个带有空对象ObjCRuntimeObject
的控制台消息。显然,Objective C没有/无法将字典序列化为JavaScript对象。我可以找到的一小块文档(我在这里没有再找到它作为参考)告诉我它只适用于数组。
我向苹果公司提交了一份错误报告:19464522
为什么Objective-C API提供了将所有内容转换为对象形式JavaScript但不反之亦然的方法?!
必须有可能,所以我该如何做到这一点?
答案 0 :(得分:0)
一直在试图解决这个限制的最佳方法,尝试了一些基于类的实现,但没有取得多大成功,最终得到了一个解决方法,可以归结为:
id dict = [internal evaluateWebScript:@"(function() { return { key: { key: 'VALUE' } }; })()"];
[internal callWebScriptMethod:@"log" withArguments:@[dict]];
这可以像这样包装(为简洁而省略错误处理):
static id jsDictionary(WebScriptObject *const webScript, NSDictionary *const dictionary)
{
NSData *const data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil];
NSString *const json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return [webScript evaluateWebScript:[NSString stringWithFormat:@"(function() { return %@; })()", json]];
}
然后像这样使用:
[internal callWebScriptMethod:@"log" withArguments:@[jsDictionary(internal, @{ @"key": @"VALUE" })]];