Pavel Yakimenko
Pavel Yakimenko

Reputation: 3254

Can I handle alert inside UIWebViewDelegate?

<script language="javascript">
    alert("Hell! UIWebView!");
</script>

I can see the alert message inside my UIWebView but can I handle this situation?

Update:

I'm loading a web-page into my UIWebView:

- (void)login {
    NSString *requestText = [[NSString alloc] initWithFormat: @"%@?user=%@&password=%@", DEFAULT_URL, user.name, user.password];    // YES, I'm using GET request to send password :)
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestText]];
    [webView loadRequest:request];
}

The target page contain a JS. If user name or password is incorrect this JS show alert. I have not any access to its sources. I want to handle it inside my UIWebViewDelegate.

Upvotes: 4

Views: 11583

Answers (3)

bogdansrc
bogdansrc

Reputation: 1344

This seems to do it:

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    JSContext *ctx = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    ctx[@"window"][@"alert"] = ^(JSValue *message) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"JavaScript Alert" message:[message toString] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    };
}

Note: only tested on iOS 8.

Upvotes: 4

Boog
Boog

Reputation: 3863

A better solution to this problem is to create a Category for UIWebView for the method

webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:

So that you can handle the alert event in any way that you'd like. I did this because I don't like the default behavior of UIWebView when it puts the filename of the source in the UIAlertView title. The Category looks something like this,

@interface UIWebView (JavaScriptAlert) 

- (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame;

@end

@implementation UIWebView (JavaScriptAlert)

- (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame {
    UIAlertView* dialogue = [[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil];
    [dialogue show];
    [dialogue autorelease];
}

@end

Upvotes: 15

Sixten Otto
Sixten Otto

Reputation: 14816

If by "contain a flash" you mean the page you're loading into your web view has an Adobe Flash movie in it, you're out of luck, I'm afraid. Mobile Safari doesn't support Flash, and most likely never will.

In the general case, if you want JavaScript running in a web view to communicate with the native app hosting it, you can load fake URLs (for example: "myapp://alert?The+text+of+the+alert+goes+here."). That will trigger the webView:shouldStartLoadWithRequest:navigationType: delegate method. In that method, inspect the request, and if the URL being loaded is one of these internal communications, trigger the appropriate action in your app, and return NO.

Upvotes: 3

Related Questions