2009-11-02 3 views
41

WebView가 있고 JavaScript에서 Objective-C로보기를 호출하고 싶습니다. 누군가 내가 이것을 어떻게 할 수 있는지 알고 있습니까?Javascript에서 Objective-C를 호출하는 방법?

- (BOOL)webView:(UIWebView *)webView2 
shouldStartLoadWithRequest:(NSURLRequest *)request 
navigationType:(UIWebViewNavigationType)navigationType { 

NSString *requestString = [[request URL] absoluteString]; 
NSArray *components = [requestString componentsSeparatedByString:@":"]; 

if ([components count] > 1 && 
    [(NSString *)[components objectAtIndex:0] isEqualToString:@"myapp"]) { 
    if([(NSString *)[components objectAtIndex:1] isEqualToString:@"myfunction"]) 
    { 

    NSLog([components objectAtIndex:2]); [[Airship shared] displayStoreFront]; //<- This is the code to open the Store 
    NSLog([components objectAtIndex:3]); // param2 
    // Call your method in Objective-C method using the above... 
    } 
    return NO; 
} 

return YES; // Return YES to make sure regular navigation works as expected. 
} 

그리고 자바 스크립트 :


나는 나의의 ViewController이 코드가

function store(event) 
{ 
    document.location = "myapp:" + "myfunction:" + param1 + ":" + param2; 
} 

을하지만 아무 반응이 없습니다.

+0

는 https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DisplayWebContent/Tasks/JavaScriptFromObjC.html이 URL를 시도? – kamleshwar

+0

[Javascript에서 Objective C 메소드를 호출하고 iOS의 Javascript로 데이터를 보내는 방법은?] (http://stackoverflow.com/questions/9826792/how-to-invoke-objective-c-method-from- javascript 및 send-back-data-to-javascrip) – zekel

+0

Sixten Otto의 응답에 대한 자세한 예제는 http://stackoverflow.com/questions/21927612/call-objective-c-method-from-javascript/ 25465329 # 25465329 –

답변

1

앱을한다고 가정하면 PhoneGap이 어떻게 구현되는지 (또는 사용할지) 확인할 수 있습니다. JS와 OBJ-C 사이의 앞뒤 통신을 지원하는 라이브러리입니다. 또한 다른 라이브러리와 솔루션도 있습니다.

웹 앱 (사용자가 Mobile Safari에서 가져 오는 것)에 대해 이야기하고 있다면 Objective-C를 사용할 수 없습니다.

+0

분명히 사실이 아닙니다. – MJB

52

UIWebView의 표준 해결 방법은 UIWebViewDelegate을 설정하고 webView:shouldStartLoadWithRequest:navigationType: 메서드를 구현하는 것입니다. 자바 스크립트 코드에서 앱에 전달하려는 정보를 인코딩 일부 가짜 URL로 이동, 같은 말 :

대리자 방법에
window.location = "fake://myApp/something_happened:param1:param2:param3"; 

는, 이러한 가짜 URL을 찾아 당신이 필요로하는 정보를 추출, 적절한 조치를 취한 다음 NO을 반환하면 탐색이 취소됩니다. some flavor of performSelector을 사용하여 긴 처리를 연기하는 것이 가장 좋습니다.

+0

http://www.codingventures.com/2008/12/using-uiwebview-to-render-svg-files/ – Sid

+0

이 솔루션의 문제점은 "가짜 // ..."입니다. . "로드 실패, webview : shouldStartLoadWithRequest : navigationType : 호출되지 않습니다. 그것을 고치는 어떤 방법? –

+1

'webview : shouldStartLoadWithRequest : navigationType :'이 호출되기 전에 무엇이 실패 할까? (이 콜백의 요점은 시스템이 네트워크 로딩을 시작하기 전에 발생한다는 것입니다.) –

3

사람들이 말한 것과 마찬가지로 UIWebviewDelegate에서 webView : shouldStartLoadWithRequest : navigationType : 메서드를 사용해야합니다.

이 API는 http://code.google.com/p/jsbridge-to-cocoa/입니다. 매우 가볍습니다. 이미지, 문자열 및 배열을 javascript에서 objective-C로 전달할 수 있습니다.

+0

자바 스크립트에서 객관적인 이미지로 이미지를 전송할 수 없으므로 답을 편집해야 할 수도 있습니다. id는 이미지를 javascript에서 window.location 방법으로 대상 c. 또한 이미지는 로컬 기본 번들에 있습니다. –

4

Obliviux,

코드가 완벽 할 것 같습니다.

문제의 원인은 위임을 매핑하지 않아야한다는 것입니다.

어느

  1. 당신의 viewDidLoad의 .xib 파일에 파일 소유자에

또는

  1. 사용 webView.delegate = self;

를 웹보기의 대리자를 연결 .

감사

1

확인이 하나 -, 아약스의 js 함수를 호출하고, 당신이 일을 끝낼 후, 당신은 트릭 당신이 자바 스크립트의 위치를 ​​변경할 때 웹보기가 트리거 될 것입니다 알고있는 응답을 얻기 위해 객관적인 C를 사용하고 understanding XMLHttpRequest responses using this (or other javascript) functions? 그래서 자바 스크립트 호출이나 실제 요청을 알기 위해 위치를 확인할 수 있습니다.

2

이 방법에 문제가 있습니다. 아이폰 장치에 여러 메시지를 보내고 싶었지만 모든 메시지를 순차적으로 처리 할 수 ​​없기 때문에 "겹쳐진"것처럼 보였습니다.

예 :

window.location = "app://action/foo"; 
window.location = "app://action/bar"; 

동작 foo이 실행되지 않았다 :이 코드를 실행할 때. 내가해야 할 일을했을 무엇

다음 :이 방법으로

waitingForMessage = false; 

function MsgProcessed(){ 
    waitingForMessage = false; 
} 

function SyncLaunchURL(url){ 
    if (waitingForMessage){ 
     setTimeout(function(){SyncLaunchURL(url)},100); 
    }else{ 
     window.location = url 
     waitingForMessage = true; 
    } 
} 

SyncLaunchURL("app://action/foo"); 
SyncLaunchURL("app://action/bar"); 

을, 아이폰은 전화를 처리 한 후 MsgProcessed()를 호출 할 수있다. 이 방법은 나를 위해 작동하고 어쩌면 같은 문제가있는 사람을 도웁니다!

+0

그냥'setTimeout'과 비동기 적으로 창 위치를 설정하면 작동하지 않습니다? – pqnet

+0

여전히 문제가 있습니다. 그게 if window.location이 처리되지 않으면 "location"이 삭제됩니다. –

+0

내 대답을 참조하십시오, 그것은 폴링이나 예상 지연 없이이 문제를 해결할 것 .. setTimeout 솔루션은 매우 우아하지 않습니다 :) – talkol

32

JS에서 objective c를 호출하는 window.location 메서드는 권장되지 않습니다. 문제의 한 예 : 두 개의 바로 연속 통화를 할 경우 (너무 빨리 위치를 변경할 수 없기 때문에) 하나가 무시됩니다 - 직접 시도 ..

나는 다음과 같은 대체 방법 추천 :

function execute(url) 
{ 
    var iframe = document.createElement("IFRAME"); 
    iframe.setAttribute("src", url); 
    document.documentElement.appendChild(iframe); 
    iframe.parentNode.removeChild(iframe); 
    iframe = null; 
} 

execute 함수를 반복적으로 호출하고 각 호출이 자체 iframe에서 실행되기 때문에 호출이 신속하게 무시되면 안됩니다.

크레디트 to this guy.

+1

마지막 줄에서 iframe에'null '을 지정해야하는 이유는 무엇입니까? (쓰레기 수집을 시행하거나 다른 이익을주지 않습니다) –

+0

당신은 내 사람입니다. –

+0

이 질문에 나를 도울 수 있습니까? http://stackoverflow.com/q/43867801/3378413 –

관련 문제