WebScriptObject 传递 NSDictionary(关联数组/对象)
Posted
技术标签:
【中文标题】WebScriptObject 传递 NSDictionary(关联数组/对象)【英文标题】:WebScriptObject pass NSDictionary (associative array / object) 【发布时间】:2015-01-13 23:23:49 【问题描述】:我正在使用 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 的方法,但反之却没有?!
一定有可能,那我该如何实现呢?
【问题讨论】:
【参考方案1】:我也一直在摸索解决此限制的最佳方法,尝试了一些基于类的实现但没有取得多大成功,最终找到了一种解决方法,归结为:
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" )]];
【讨论】:
以上是关于WebScriptObject 传递 NSDictionary(关联数组/对象)的主要内容,如果未能解决你的问题,请参考以下文章