Невозможно запустить proj4.js в JavaScriptCore JContext

Мне не удалось запустить proj4.js (проекты Javascript, http://proj4js.org) в цели iOS -C JavaScriptCore JSContext. После попытки запустить его в контексте функции proj4 недоступны для последующего кода Javascript, который я пытаюсь запустить в том же JContext.

После включения обработки исключений Javascript в JContext я обнаружил, что получаю следующее исключение при попытке запустить proj4.js:

TypeError: undefined не является объектом (оценка 'b.proj4=a()')

Я успешно запустил тот же proj4.js в WKWebView через некоторый HTML, который загружает скрипт. Там нормально работает. Но теперь мне нужно, чтобы он работал в JContext, где я его использую и преобразовываю объекты из вывода 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"];

Таким образом, оказывается, что сам контекст является функциональным. Возможно, есть какие-то проблемы с окружением или конфигом JContext, но я ничего не могу придумать.

РЕДАКТИРОВАТЬ: Строка в proj4.js, которая вызывает исключение:

"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.proj4=a()

Таким образом, это будет означать, что ни «окно», ни «глобальный», ни «я» не определены в среде JSContext (я думаю?). Я новичок в JavaScriptCore (и умеренно новичок в JavaScript), поэтому я не уверен, что делать дальше (но я продолжу исследования).


person Son of a Beach    schedule 05.11.2016    source источник


Ответы (1)


Согласно редактированию моего вопроса, ни «окно», ни «глобальный», ни «я», по-видимому, не определены в новом JContext. Это имеет смысл для «окна» (не так уверен насчет «глобального» или «самостоятельного»!!!).

Итак, есть два возможных исправления, которые я придумал:

  1. Это первое исправление работает для proj4.js, но не работает для двух последующих сценариев JavaScript, которые мне нужно было запустить. Это исправление заключалось в том, чтобы просто добавить следующую строку кода Objective-C перед попыткой запустить proj4.js:

    [context evaluateScript:@"var global = this;"];
    

тогда строка проблемы (последняя строка моего исходного кода в исходном вопросе) работает нормально!

  1. Это исправление является более полным, поскольку оно должно работать для любого JavaScript, который может работать в обычном веб-браузере. Однако он более тяжеловесен. Для этого решения требуется только одно изменение — заменить строку «init» JContext, чтобы получить JContext из UIWebView:

    JSContext * context = [[[UIWebView alloc] init] valueForKeyPath : @"documentView.webView.mainFrame.javaScriptContext" ];
    

Хотя я бы предпочел избегать создания экземпляра веб-представления, слишком много недостающих компонентов не позволяет использовать необработанный JContext для сложных Javascripts. Я бы также предпочел использовать WKWebView, а не UIWebView, но в настоящее время JContext WKWebView недоступен.

person Son of a Beach    schedule 06.11.2016
comment
Это мне очень помогло! Не могу поверить, что это единственный способ, которым это сработает, и что это единственное решение, которое я нашел в Интернете. - person dizza213; 07.11.2018