UIWebView JavaScript perdendo referência ao namespace JSContext do iOS (objeto)

Estou trabalhando em um aplicativo de prova de conceito que aproveita a comunicação bidirecional entre o Objective C (iOS 7) e JavaScript usando o WebKitJavaScriptCore estrutura. Finalmente, consegui fazê-lo funcionar como esperado, mas me deparei com uma situação em que o UIWebView perde sua referência ao objeto iOS que eu criei via JSContext.

O aplicativo é um pouco complexo, aqui estão os princípios básicos:

Estou executando um servidor Web no dispositivo iOS (CocoaHTTPServer)O UIWebView carrega inicialmente uma URL remota e depois é redirecionado de volta paralocalhost como parte do fluxo do aplicativo (pense em OAuth)A página HTML que o aplicativo hospeda (no host local) tem o JavaScript que deveria estar falando com o meu código do iOS

Aqui está o lado do iOS, meu 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

E as partes pertinentes do ViewController.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);
}

Aqui está o lado (simplificado para fins de pergunta) do 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>

Agora, em quase todos os casos, isso funciona lindamente, eu vejoios is: object no UIWebView e no console do Xcode. Muito legal. Mas em um cenário específico, 100% do tempo, isso falha após um certo número de redirecionamentos no UIWebView e, quando a página acima finalmente é carregada, é exibido:

ios é: indefinido

... e o restante da lógica JS é encerrada porque a chamada subsequente paraios.jsLog nosetContent A função resulta em uma exceção de objeto indefinida.

Então, finalmente, minha pergunta:o que poderia / pode causar a perda de um JSContext? Examinei a "documentação" nos arquivos .h do JavaScriptCore e descobri que a única maneira de isso acontecer é se não houver maisstrong referências aoJSContext, mas no meu caso, tenho um próprio, para que não pareça certo.

Minha única outra hipótese é que isso tem a ver com a maneira como estou adquirindo oJSContext referência:

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

Estou ciente de que issotalvez não seja oficialmente suportado pela Apple, embora eu tenha encontrado pelo menos um SO'er que disse que ele tinha um aplicativo aprovado pela Apple que usava esse mesmo método.

EDITAR

Devo mencionar, eu implementeiUIWebViewDelegate para verificar o JSContext após cada redirecionamento no UIWebView da seguinte forma:

-(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');"];
}

Isso funciona em todos os casos, mesmo quando minha página da web finalmente carrega e relataios is: undefined o método acima escreve simultaneamenteCan see JS from obj c para o console do Xcode. Isso parece indicar que o JSContext ainda é válido e que, por algum motivo, ele simplesmente não é mais visível no JS.

Peço desculpas pela questão muito extensa, há tão pouca documentação sobre isso que achei que quanto mais informações eu pudesse fornecer, melhor.

questionAnswers(2)

yourAnswerToTheQuestion