Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Blakeasd

macrumors 6502a
Original poster
Dec 29, 2009
643
0
I am fooling around with using Javascript to call Objective-C and I can't get this seemingly simple task to work. I'd like to launch a simple NSAlert and write an NSLog, but I cannot get these results. Here is my AppDelegate implementation:

Code:
-(void)awakeFromNib{
    [self.webView setDrawsBackground:NO];
  
    NSString *resourcesPath = [[NSBundle mainBundle] resourcePath];
    NSString *htmlPath = [resourcesPath stringByAppendingString:@"/index.html"];
    [[self.webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:htmlPath]]];
    
    
    [[self.webView windowScriptObject] setValue:self forKey:@"AppDelegate"];
}


- (void)showMessage:(NSString *)message
{  
    NSRunAlertPanel(@"Message from JavaScript", message, nil, nil, nil);
    NSLog(@"foo");
}

and the html:

Code:
<!DOCTYPE html>

<html>

<body>


<input id="message_button" type="button" value="Show Message" onClick="window.AppDelegate.showMessage_('Hello there...');" />


</body>

</html>

I get one button like I expect, but clicking it has no effect. Interestingly enough, adding a simple alert instead of my Objective-C code doesn't work either. It does however work in Safari when I run the exact same HTML code in my browser.

Why won't things work in my WebView?
 
Why won't things work in my WebView?

Sounds like Javascript is disabled in WebView. (You can check just by rendering straight HTML into the WebView.)

On Andriod, the details are explained on the following page with instructions on how to enable Javascript in the Android WebView:

http://developer.android.com/guide/webapps/webview.html#UsingJavaScript

This might provide some ideas.

http://will.thimbleby.net/script/

On terminology, your example is "calling Javascript from Objective-C". Not calling "Objective-C from Javascript".
 
Last edited:
mrichmon said:
On terminology, your example is "calling Javascript from Objective-C". Not calling "Objective-C from Javascript".

No, he's right. He wants a button press in a web view (JS) to call some Obj-C code.

I found this Apple Developer Document titled something that looks super helpful for you:

https://developer.apple.com/library/mac/documentation/appleapplications/Conceptual/SafariJSProgTopics/Tasks/ObjCFromJavaScript.html
 
Last edited:
Sounds like Javascript is disabled in WebView. (You can check just by rendering straight HTML into the WebView.)

On Andriod, the details are explained on the following page with instructions on how to enable Javascript in the Android WebView:

http://developer.android.com/guide/webapps/webview.html#UsingJavaScript

This might provide some ideas.

http://will.thimbleby.net/script/

On terminology, your example is "calling Javascript from Objective-C". Not calling "Objective-C from Javascript".

I've checked and Javascript is enabled for my WebView. I've done some more tests and found that some Javascript code will work while other Javascript code does not.

I found this Apple Developer Document titled something that looks super helpful for you:

https://developer.apple.com/library...ariJSProgTopics/Tasks/ObjCFromJavaScript.html

Thanks! But I've already read that.

This HTML code's Javascript will work:

Code:
<!DOCTYPE html>
<html>
<body>

<h1>My First JavaScript</h1>
<p>Click the button to display the date.</p>
<p id="demo"></p>

<button type="button" onclick="myFunction()">Try it</button>

<script>
function myFunction()
{
document.getElementById("demo").innerHTML = Date();
}
</script>

</body>
</html>

this HTML code's Javascript will not:

Code:
<!DOCTYPE html>
<html>
<body>

<p>Click the button to display an alert box.</p>

<button onclick="myFunction()">Try it</button>

<script>
function myFunction()
{
alert("I am an alert box!");
}
</script>

</body>
</html>

Both of these examples work perfectly in Safari, though. :confused:
 
I've checked and Javascript is enabled for my WebView. I've done some more tests and found that some Javascript code will work while other Javascript code does not.



Thanks! But I've already read that.

This HTML code's Javascript will work:

Code:
<!DOCTYPE html>
<html>
<body>

<h1>My First JavaScript</h1>
<p>Click the button to display the date.</p>
<p id="demo"></p>

<button type="button" onclick="myFunction()">Try it</button>

<script>
function myFunction()
{
document.getElementById("demo").innerHTML = Date();
}
</script>

</body>
</html>

this HTML code's Javascript will not:

Code:
<!DOCTYPE html>
<html>
<body>

<p>Click the button to display an alert box.</p>

<button onclick="myFunction()">Try it</button>

<script>
function myFunction()
{
alert("I am an alert box!");
}
</script>

</body>
</html>

Both of these examples work perfectly in Safari, though. :confused:

How could alert possibly work in a WebView? If you want to implement something like that, send a message to your Obj-C code from the JavaScript and produce an NSAlert with the contents of the message.
 
How could alert possibly work in a WebView? If you want to implement something like that, send a message to your Obj-C code from the JavaScript and produce an NSAlert with the contents of the message.

alert(); isn't Objective-C . This works perfectly fine in an example app I saw using a WebView.
After redoing my app it works for some reason.
 
...
Both of these examples work perfectly in Safari, though. :confused:

You have the perfect starting point to make incremental changes.

Start with the one that doesn't work. One line at a time, change that one line to whatever is in the one that works. If it still doesn't work, choose the next line to change. Continue until it starts working.

You can do it in reverse, too. Change one line of the working one to be whatever line is in the not-working one. Repeat until it doesn't work.

In either case, the line that changes things (not-working to working, or vice versa) is the line to focus on. Go to the original working one and change only that line. What happens? Or go to the original non-working one and change only that line. What happens?

Post your results, specifically the line that caused the non-working one to work, or the working one to not work. Post complete code of the before and after.


Making incremental changes is a basic debugging skill. If you've never used it before, this is a good opportunity to practice it.
 
You have the perfect starting point to make incremental changes.

Start with the one that doesn't work. One line at a time, change that one line to whatever is in the one that works. If it still doesn't work, choose the next line to change. Continue until it starts working.

You can do it in reverse, too. Change one line of the working one to be whatever line is in the not-working one. Repeat until it doesn't work.

Sooo slow. Do a binary search - it'll be take a tiny fraction of the time. Change half the program to match its counterpart. Worst case will be log(n) vs n steps where n is the number of lines that differ between the two.
 
alert(); isn't Objective-C . This works perfectly fine in an example app I saw using a WebView.
After redoing my app it works for some reason.

The alert javascript function doesn't work on a basic WebView. If you have seen a WebView where it works, it's likely that such WebView is using a WebUIDelegate that implements the method "webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:".

Concerning the code you originally posted, my impression is that you have forgotten to override "isSelectorExcludedFromWebScript:". For security reasons, all methods are excluded by default even if you have registered the class with a WebScriptObject. In your case you should add this to your AppDelegate:

Code:
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
    if(aSelector==@selector(showMessage:))
        return NO;
    return YES;
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.