2010-02-18 5 views
13

Windows에서 "Shell.Explorer"ActiveX 컨트롤이 응용 프로그램에 포함되어 있으면 웹 페이지의 스크립트가 호스팅 응용 프로그램을 호출 할 수 있도록 IDispatch를 구현하는 개체에 "외부"처리기를 등록 할 수 있습니다 .임베디드 웹킷 - 스크립트 콜백 방법?

<button onclick="window.external.Test('called from script code')">test</button> 

이제 Mac 개발로 옮겨서 내 코코아 응용 프로그램에 포함 된 WebKit에서 비슷한 작업을 할 수 있다고 생각했습니다. 그러나 실제로 스크립트가 호스팅 응용 프로그램으로 다시 호출 할 수있는 기능이없는 것 같습니다.

한 가지 조언은 window.alert을 연결하고 스크립트를 통해 서식이 지정된 메시지 문자열을 경고 문자열로 전달하는 것이 었습니다. 또한 WebKit을 NPPVpluginScriptableNPObject를 사용하여 NPAPI 플러그인을 호스팅하는 응용 프로그램으로 전달할 수 있는지 궁금합니다.

내가 누락 된 항목이 있습니까? WebView를 호스팅하고 스크립트가 호스트와 상호 작용할 수있게하는 것이 정말로 어렵습니까?

답변

30

다양한 WebScripting 프로토콜 방법을 구현해야합니다.

@interface WebController : NSObject 
{ 
    IBOutlet WebView* webView; 
} 

@end 

@implementation WebController 

//this returns a nice name for the method in the JavaScript environment 
+(NSString*)webScriptNameForSelector:(SEL)sel 
{ 
    if(sel == @selector(logJavaScriptString:)) 
     return @"log"; 
    return nil; 
} 

//this allows JavaScript to call the -logJavaScriptString: method 
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)sel 
{ 
    if(sel == @selector(logJavaScriptString:)) 
     return NO; 
    return YES; 
} 

//called when the nib objects are available, so do initial setup 
- (void)awakeFromNib 
{ 
    //set this class as the web view's frame load delegate 
    //we will then be notified when the scripting environment 
    //becomes available in the page 
    [webView setFrameLoadDelegate:self]; 

    //load a file called 'page.html' from the app bundle into the WebView 
    NSString* pagePath = [[NSBundle mainBundle] pathForResource:@"page" ofType:@"html"]; 
    NSURL* pageURL = [NSURL fileURLWithPath:pagePath]; 
    [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:pageURL]]; 
} 


//this is a simple log command 
- (void)logJavaScriptString:(NSString*) logText 
{ 
    NSLog(@"JavaScript: %@",logText); 
} 

//this is called as soon as the script environment is ready in the webview 
- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowScriptObject forFrame:(WebFrame *)frame 
{ 
    //add the controller to the script environment 
    //the "Cocoa" object will now be available to JavaScript 
    [windowScriptObject setValue:self forKey:@"Cocoa"]; 
} 

@end 

컨트롤러에이 코드를 구현 한 후, 당신은 이제 자바 스크립트 환경에서 Cocoa.log('foo');를 호출 할 수 있고, logJavaScriptString: 메소드가 호출됩니다 다음은 기본 예제입니다.

+0

[webView mainFrame] loadData : didClearWindowObject를 발생시킵니다.? 나는 [webView setFrameLoadDelegate : self]를 가지고있다. setup하지만 breakpoint를 시도 할 때 windowScriptObject를 설정하지 않습니다. – Luke

+1

나는이 방법으로 돌아 다니고 있지만, 코코아에서 콜백 (callback)으로 핸들러 (JS 함수)를 어떻게 호출 할까? 물론'WebView'에서'windowScriptObject'를 얻을 수는 있지만'Cocoa'가 그것이 속한'WebScriptObject' 인스턴스를 알 수있는 방법이 있습니까? –

+0

좋은 사람. 감사! ;-) –

1

이것은 JavaScriptCore 프레임 워크와 함께 WebScriptObject API과 함께 사용하면 매우 쉽습니다.

관련 문제