我无法在iOS Objective-C JavaScriptCore JSContext中运行proj4.js(投影Javascript,http://proj4js.org)。尝试在上下文中运行它后,proj4函数不能用于我尝试在同一个JSContext中运行的后续Javascript代码。
在JSContext上启用Javascript异常处理后,我发现在尝试运行proj4.js时出现以下异常:
TypeError:undefined不是对象(评估' b.proj4 = a()')
我已经通过一些加载脚本的HTML在WKWebView中成功运行了相同的proj4.js。那里工作得很好。但我现在需要它在JSContext中运行,我在其中使用它并将对象从Javascript输出转换为Objective-C对象。
这里的代码失败了:
NSString *proj4Path = [[NSBundle mainBundle] pathForResource:@"proj4" ofType:@"js" inDirectory:@"proj4"];
NSString *proj4JS = [NSString stringWithContentsOfFile:proj4Path usedEncoding:nil error:nil];
JSContext *context = [[JSContext alloc] init];
context.exceptionHandler = ^(JSContext *context, JSValue *exception) {
NSLog(@"JAVASCTIPT EXCEPTION: %@", exception);
};
[context evaluateScript:proj4JS]; // FAILS HERE
如果我用一个非常简单的JavaScript替换最后一行,它可以正常工作。例如,
[context evaluateScript:@"1 + 1"];
因此看起来上下文本身是有用的。也许JSContext的环境或配置存在一些问题,但我无法想到任何事情。
编辑:导致异常的proj4.js中的行是:
"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.proj4=a()
所以这表明两个窗口都没有'也不是全球的'也不是' self'在JSContext环境中定义(我认为?)。我是JavaScriptCore的新手(也是JavaScript的新手),所以我不确定从哪里开始(但我会继续研究)。
答案 0 :(得分:1)
根据我的问题的编辑,没有'窗口'也不是全球的'也不是' self'似乎是在新的JSContext中定义的。这对于“窗口”来说是有意义的。 (不太确定' global'或者' self' !!!)。
因此我提出了两种可能的修复方法:
第一个修复程序适用于proj4.js,但不适用于我需要运行的两个后续JavaScripts。这个修复是在尝试运行proj4.js之前简单地添加以下的Objective-C代码:
[context evaluateScript:@"var global = this;"];
然后问题行(原始问题中原始代码的最后一行)运行正常!
此修复程序更全面,因为它适用于任何可以在普通Web浏览器中运行的JavaScript。但是,它更加笨拙。对于此解决方案,唯一需要的更改是替换JSContext' init'从UIWebView获取JSContext的行:
JSContext * context = [[[UIWebView alloc] init] valueForKeyPath : @"documentView.webView.mainFrame.javaScriptContext" ];
虽然我更喜欢避免实例化Web视图,但是对于复杂的Javascripts,使用原始JSContext的组件太多了。我也更喜欢使用WKWebView而不是UIWebView,但目前,WKWebView的JSContext不可用。