UIWebView JavaScript теряет ссылку на пространство имен iOS JSContext (объект)

Я работал над приложением для проверки концепции, которое использует двустороннюю связь между Objective C (iOS 7) и JavaScript с помощью WebKitJavaScriptCore фреймворк. Я наконец смог заставить его работать как положено, но столкнулся с ситуацией, когда UIWebView теряет свою ссылку на объект iOS, который я создал с помощью JSContext.

Приложение немного сложное, вот основы:

Я использую веб-сервер на устройстве iOS (CocoaHTTPServer)UIWebView изначально загружает удаленный URL, а затем перенаправляется обратно наlocalhost как часть потока приложения (думаю, OAuth)HTML-страница, которую размещает приложение (на локальном хосте), имеет JavaScript, который должен общаться с моим кодом iOS

Вот сторона iOS, мой ViewController.h:

#import <UIKit/UIKit.h>
#import <JavaScriptCore/JavaScriptCore.h>

// These methods will be exposed to JS
@protocol DemoJSExports <JSExport>
-(void)jsLog:(NSString*)msg;
@end

@interface Demo : UIViewController <UserInfoJSExports, UIWebViewDelegate>
@property (nonatomic, readwrite, strong) JSContext *js;
@property (strong, nonatomic) IBOutlet UIWebView *webView;
@end

И соответствующие части ViewController's.m:

-(void)viewDidLoad {
    [super viewDidLoad];

    // Retrieve and initialize our JS context
    NSLog(@"Initializing JavaScript context");
    self.js = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

    // Provide an object for JS to access our exported methods by
    self.js[@"ios"] = self;

    // Additional UIWebView setup done here...
}

// Allow JavaScript to log to the Xcode console
-(void)jsLog(str) {
    NSLog(@"JavaScript: %@", str);
}

Вот (упрощенная ради этого вопроса) сторона HTML / JS:

<html>
<head>
<title>Demo</title>
<script type="text/javascript">
    function setContent(c, noLog){
        with(document){
            open();
            write('<p>' + c + '</p>');
            close();
        }

        // Write content to Xcode console
        noLog || ios.jsLog(c);
    }    
</script>
</head>
<body onload="javascript:setContent('ios is: ' + typeof ios)">
</body>
</html>

Теперь, почти во всех случаях это работает прекрасно, я вижуios is: object как в UIWebView, так и в консоли Xcode. Очень круто. Но в одном конкретном сценарии, в 100% случаев, происходит сбой после определенного количества перенаправлений в UIWebView, и после полной загрузки приведенной выше страницы написано:

ios is: undefined

... и остальная часть логики JS завершается, потому что последующий вызовios.jsLog вsetContent Функция приводит к исключению неопределенного объекта.

Итак, наконец мой вопрос:что может / может привести к потере JSContext? Я покопался в "документации" в файлах JavaScript.Core и обнаружил, что единственный способ, которым это должно произойти, это если больше нетstrong ссылки наJSContext, но в моем случае у меня есть один, так что это не так.

Моя единственная другая гипотеза заключается в том, что это связано с тем, как яJSContext ссылка:

 self.js = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

Я знаю, что этоможет не быть официально поддержанный Apple, хотя я нашел по крайней мере одну SO'er, которая сказала, что у него было одобренное Apple приложение, которое использовало тот же метод.

РЕДАКТИРОВАТЬ

Я должен упомянуть, я реализовалUIWebViewDelegate таким образом проверить JSContext после каждого перенаправления в UIWebView:

-(void)webViewDidFinishLoad:(UIWebView *)view{
    // Write to Xcode console via our JSContent - is it still valid?
    [self.js evaluateScript:@"ios.jsLog('Can see JS from obj c');"];
}

Это работает во всех случаях, даже когда моя веб-страница наконец загружается и сообщаетios is: undefined вышеуказанный метод одновременно пишетCan see JS from obj c к консоли Xcode. Казалось бы, это указывает на то, что JSContext все еще действует, и по какой-то причине его просто больше не видно из JS.

Извиняюсь за очень многословный вопрос, там так мало документации по этому вопросу, что я подумал, что чем больше информации я смогу предоставить, тем лучше.

Ответы на вопрос(2)

Ваш ответ на вопрос