2

我正在使用 aWebScriptObject在 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 的方法,但反之却没有?!

一定有可能,那么我该如何实现呢?

4

1 回答 1

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" })]];
于 2015-11-19T07:00:37.310 回答