2010-02-18 26 views
13

Trên cửa sổ, khi điều khiển ActiveX "Shell.Explorer" được nhúng trong ứng dụng, bạn có thể đăng ký trình xử lý "bên ngoài" trên đối tượng triển khai IDispatch, sao cho tập lệnh trên trang web có thể gọi ra ứng dụng lưu trữ .Webkit nhúng - tập lệnh gọi lại như thế nào?

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

Bây giờ, ive đã chuyển sang phát triển Mac và nghĩ rằng tôi có thể làm việc tương tự từ WebKit được nhúng trong ứng dụng Cocoa của tôi. Nhưng, có thực sự dường như không có bất kỳ cơ sở nào để cho phép các tập lệnh gọi lại cho ứng dụng lưu trữ.

Một lời khuyên là móc window.alert và nhận tập lệnh để chuyển chuỗi tin nhắn được định dạng làm chuỗi cảnh báo. Tôi cũng tự hỏi liệu WebKit có lẽ có thể được chuyển hướng đến một ứng dụng được lưu trữ trên NPAPI plugin sử dụng NPPVpluginScriptableNPObject hay không.

Tôi có thiếu gì đó không? Có thực sự khó khăn để lưu trữ một WebView và cho phép các tập lệnh tương tác với máy chủ không?

Trả lời

30

Bạn cần triển khai các phương thức giao thức WebScript khác nhau. Dưới đây là một ví dụ cơ bản:

@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 

Sau khi thực hiện mã này trong điều khiển của bạn, bây giờ bạn có thể gọi Cocoa.log('foo'); từ môi trường JavaScript và phương pháp logJavaScriptString: sẽ được gọi.

+0

Không [webView mainFrame] loadData: kích hoạt didClearWindowObject:? Tôi có [webView setFrameLoadDelegate: self]; thiết lập nhưng điều này không phải là thiết lập windowScriptObject khi tôi thử một breakpoint. – Luke

+1

Tôi đã nhận nó chạy theo cách này, nhưng làm thế nào để bạn gọi một xử lý (JS chức năng) từ Cocoa, như một cuộc gọi lại rằng một cái gì đó đã xảy ra trong ca cao. Tất nhiên bạn có thể nhận được 'windowScriptObject' từ' WebView' nhưng có cách nào để 'Cocoa' biết được cá thể' WebScriptObject' nào thuộc về nó không? –

+0

Tuyệt vời nhất. Cảm ơn! ;-) –

1

Việc này rất dễ thực hiện với WebScriptObject API kết hợp với khung JavaScriptCore.

Các vấn đề liên quan