无法在 JavaScriptCore JSContext 中运行 proj4.js

Posted

技术标签:

【中文标题】无法在 JavaScriptCore JSContext 中运行 proj4.js【英文标题】:Unable to run proj4.js in JavaScriptCore JSContext 【发布时间】:2016-11-05 07:48:37 【问题描述】:

我无法在 ios Objective-C javascriptCore JSContext 中运行 proj4.js(投影 Javascript,http://proj4js.org)。尝试在上下文中运行它后,proj4 函数对我尝试在同一 JSContext 中运行的后续 Javascript 代码不可用。

在 JSContext 上启用 Javascript 异常处理后,我发现在尝试运行 proj4.js 时出现以下异常:

TypeError: undefined is not an object (evalating '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()

所以这表明在 JSContext 环境中既没有定义“窗口”也没有定义“全局”或“自我”(我认为?)。我是 JavaScriptCore 的新手(对 JavaScript 也比较陌生),所以我不知道从哪里开始(但我会继续研究)。

【问题讨论】:

【参考方案1】:

根据我的问题的编辑,“窗口”、“全局”和“自我”似乎都没有在新的 JSContext 中定义。这对于“窗口”是有意义的(对于“全局”或“自我”不太确定!!!)。

所以我想出了两个可能的修复方法:

    第一个修复适用于 proj4.js,但不适用于我需要运行的两个后续 JavaScript。此修复是在尝试运行 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 视图,但缺少的组件太多,无法将原始 JSContext 用于复杂的 Javascript。我也更喜欢使用 WKWebView 而不是 UIWebView,但目前 WKWebView 的 JSContext 不可用。

【讨论】:

这对我帮助很大!不敢相信这是唯一可行的方法,而且这是我在互联网上找到的唯一解决方案。

以上是关于无法在 JavaScriptCore JSContext 中运行 proj4.js的主要内容,如果未能解决你的问题,请参考以下文章

如果无法访问 UIWebView 的运行时,为啥要在 iOS7 中使用 JavaScriptCore?

如何使用 JavaScriptCore 将错误记录到 XCode?

iOS9 上的 JavaScriptCore 崩溃

Swift JavaScriptCore 不能处理大文件?

在 JavaScriptCore 中获取默认导出

JavaScriptCore 外部数组