在WebView实例中的
JavaScript与WebViewDelegate之间进行通信时,JavaScript类型和Objective-C类型会来回转换.例如,当从JavaScript调用Objective-C函数时,字符串变为NSString,数字变为NSNumber,而Object变为WebScriptObject.
其他的处理非常简单,但WebScriptObject似乎很奇怪.
当传递像{“foo”:1,“bar”:2}这样的字典时,我看到的大多数代码都使用valueForKey提取属性,例如[[arg valueForKey:@“foo”] intValue] == 1
但是如果你不确定该物业是否存在呢?如果键是可选的怎么办? [arg valueForKey:@“baz”]抛出异常.
我能做的一件事就是
@try { foo = [[arg valueForKey:@"baz"] intValue]; } @catch (NSException* e) { foo = 0; }
但我听说Objective-C中的异常是不安全的,不应该用于流量控制.
我能想到的另一种方法是这里使用的方法的一些变化:http://edotprintstacktrace.blogspot.com/2011/10/sample-webscriptobject-javascript.html
换句话说:1.使用evaluateWebScript定义实现Object.keys的JavaScript函数2.在WebScriptObject 3上调用该函数.遍历返回的键数组,并且只有在找到匹配项时才调用valueForKey.
对我来说,这看起来非常低效.一定有更好的方法……有吗?
解决方法
从OS X 10.9和iOS 7开始,有一种更简单的方法可以做到这一点. Apple引入了一个名为JSValue的类,它可以用来将JavaScript对象桥接到常规的ObjC对象:
// WebScriptObject *options; obtained from a callback in ObjC id objCObject = [[options JSValue] toObject]; if ([objCObject isKindOfClass:[NSArray class]]) { for (id object in objCObject) { NSLog(@"object: %@",object); } } else if ([objCObject isKindOfClass:[NSDictionary class]]) { for (id<NSCopying> key in [objCObj allKeys]) { NSLog(@"object for key %@: %@",key,[objCObject objectForKey:key]); } }