Calling Javascript from Objective-C via WebScriptObject
I decided I would change how I implement printing in my Cocoa app by having my app provide string-data to a webpage in an embedded webview, and then I would print that webview/frame.
The problem is that my code isn't being called and I don't see an error being returned.
Here is the setup:
1) Use 开发者_JAVA技巧Dashcode and build a webpage. There is no "form" container in the generated document, but it has fields like this:
<input id="customerNameField" type="text" name="" value="">
<input id="customerStreetField" type="text" name="" value="">
2) In IB, I create a window, toss in a WebView, link it to an outlet in my controller and create an NSURLRequest, grab my WebView's mainFrame and have it load the request. That works, the page is displayed in the WebView. Code:
[[wv mainFrame] stopLoading];
request = [NSURLRequest requestWithURL:currentPrintTemplateURL];
[[wv mainFrame] loadRequest:request];
3) I want to set the value of the customerNameField in my webView, so I do the following:
3A) Use a class-method on my controller that allows all keys to be accessible to the bridge:
+(BOOL)isKeyExcludedFromWebScript:(const char *)name {
// TODO: Implement specific blocks here; but for now let it all through
NSLog(@"Excluding nothing from WebScript");
return NO;
}
3B) Add a JavaScript function to my HTML file, which I want to call with arguments from Cocoa:
function populateRepairFields(repairCase) {
document.getElementById("customerNameField").value = repairCase;
}
(I know the javascript single-line-of-code works because I can add a button to my page, trigger the function in onClick and the code modifies the value of the customerNamefield.)
3C) Ask the webview for it's windowScriptObject, create an NSArray of arguments to be passed to the javascript function, and then execute them using the callWebScriptMethod method:
// grab the data we want to send to the javascript
NSString *customerFirstName = [self valueForKeyPath:@"currentRepairCase.customer.firstName"];
NSLog(@"(debug) Ensure we have a value - customerFirstName = %@", customerFirstName);
// build the array whose items will be passed as arguments to the javascript method
NSArray * args = [NSArray arrayWithObjects:customerFirstName, nil];
// get the windowScriptObject, then (debug) log the output so we can be sure it is not null
ws = [wv windowScriptObject];
NSLog(@"WebScriptObject = %@", ws);
//Then call the javascript method via the bridge, logging the output so we can see if there is an WSUndefined error returned (results are the same even if we don't wrap it in an NSLog)
NSLog(@"WS ERR: %@", [ws callWebScriptMethod:@"populateRepairFields" withArguments:args]);
4) All that. And .. nothing. I don't see the class method being called (3A), and don't get an WSUndefined or any other error message (3C), and I don't see an alert if I tried to add a javascript alert in my code.
I thought maybe I would need to setup a delegate for the WebView, but after checking the docs, I don't see a delegate requirement for WebScript. (I then connected all the delegate outlets to my controller, but that didn't help.)
Why is my code not seemingly being called? What's missing?
Thanks..
You can only use the WebScriptObject
instance after the WebView
instance is ready, and the WebView
instance is not ready right after your call
[[wv mainFrame] loadRequest:request];
because the loading is done in the background thread automatically by WebKit. Your code should work as is, as long as you call it shortly afterwards from the webview delegate, action methods, etc.
精彩评论