在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
wich的类,该类可用于将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]);
}
}
关于javascript - 如何安全地读取WebScriptObject的属性?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10777446/