2012-12-18 8 views
4

다양한 웹 사이트를 표시하기 위해 UIWebView을 사용하려고하는 iOS 앱을 만들고 있습니다. 최근 UIWebView에 자바 스크립트를 삽입하여 window.open, window.closewindow.opener.focus의 인스턴스를 잡는 로직을 마쳤습니다. 즉, 위의 JS 함수를 재정의하는 JS를 삽입합니다. 여기에는 webView:shouldStartLoadWithRequest:navigationType 메소드에서 catch 할 수있는 특정 스키마로 iframe을 만드는 작업이 포함됩니다. 이제는 동일한 창에서로드하지 않고 UIWebView을 새로 작성하는 window.open을 포함하여 모두 정상적으로 작동합니다.UIWebView Javascript Window to Window Communication

이제 Windows간에 JS 통신을위한 가능한 솔루션이없는 경우 문제가 발생했습니다. 하위 창이 window.opener 또는 window.parent으로 전화를 걸려고하면 항상 null 값을 반환하므로 원래 웹보기로 다시 통신 할 수 없습니다.

iOS 브라우저가 window-to-window 통신을 효과적으로 수행 할 수 있는지 확인하기 위해 iPhone 9 브라우저 중 Safari 만 효과적으로이 통신을 효과적으로 수행 할 수있었습니다. 이로 인해 나는 완전한 JS 윈도우 간 통신이 불가능 해지는 것을 UIWebView과 함께보고 있다고 생각한다.

누구나 UIWebView를 모든 JS 로직, 즉 윈도우 대 윈도우 커뮤니케이션과 완벽하게 통합하는 데 성공 했습니까? 또는 JS 윈도우 간 통신이 불가능하다는 증거를 가지고 계신가요? 어떤 방향이나 조언을 주시면 감사하겠습니다. 감사!

+0

같은 문제에 작품. 행운? – drogon

+0

아직 운이 없지만, 불행히도. 내가 할 수 있었던 것은 (위에서 언급 한) 윈도우 메서드를 오버라이드하는 간단한 JS 인젝션이다. 필자의 경우 UIWebview에로드 된 웹 사이트의 Facebook 인증에서 핵심적인 문제가 발생했습니다. UIWebview에서는 인증 후 멈추게됩니다. 창에서 창으로의 통신이 없었기 때문입니다. 결국, WebView로로드 된 웹 사이트의 논리를 변경해야했습니다 (팝업 창과 함께 일반 인증 흐름을 사용하는 대신 FB로 직접 리디렉션을 사용하여 제어 할 수있는 기능이 생겼습니다). –

답변

1

가능한 해결책을 찾았습니다.

링크 된 프레임 워크로하고 webViewDidFinishLoad에 JavaScriptCore.framework을 추가

JSContext *parentCtx = [self.parentWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; 
JSContext *childCtx = [self.childWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; 
childCtx[@"window"][@"opener"] = parentCtx[@"window"]; 

을 이제 childWebView에서) (window.opener.test 호출 할 때, 그것은 parentWebView에 테스트 함수를 발사합니다!

개인 API에 대해 잘 모르겠습니다. 아이폰 OS 7 만

+0

IOS 7에 대해서만 말하는 이유는 무엇입니까? 나는 IOS 9에서 이것을 달성하려고 노력하고있다! 어떤 생각? – Daniel

+0

iOS 7이 그 순간 가장 최신이었습니다. :) – IvovDry

0

스위프트 버전

import JavaScriptCore 

    let jsContextA = webA.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") 
    let jsContextB = webB.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext")   

    //Original objc code : jsContextB[@"window"][@"opener"] = jsContextA[@"window"]; 
    jsContextB!.setObject("opener", forKeyedSubscript: "window") 
    jsContextB!.setObject(jsContextA!.objectForKeyedSubscript("window"), forKeyedSubscript: "opener")