Trigger UIAlertView from UIWebView?

Discussion in 'iOS Programming' started by Danneman101, Feb 10, 2009.

  1. Danneman101 macrumors 6502

    Joined:
    Aug 14, 2008
    #1
    I want to trigger a simple UIAlertView from the html-page loaded within a UIWebView (using html or javascript).

    Is there a way to catch events happening on the webpage loaded inside a uiwebview and pass them along to the source-code of the application?

    This is the simple alert I want displayed:

    Code:
    UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"Wazzup" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    
    ...when, for instance a button is pressed inside the webpage:
    Code:
    function disp_alert()
    {
        // SOMEHOW CALL myAlert..
    }
    
    <form>
       <input type="button" onclick="disp_alert()" value="Display alert box" />
    </form>
    

    An easier way would have been to call a javascript-alertbox. However, I can't get it to work inside a uiwebview and that makes me think that it probably is not supported:

    Code:
    function disp_alert()
    {
    	alert("Hello, wazzup");
    }
    
    <form>
       <input type="button" onclick="disp_alert()" value="Display alert box" />
    </form>
    
    }
     
  2. ghayenga macrumors regular

    Joined:
    Jun 18, 2008
    #2
    Make your controller the webview's delegate and then catch the button click in -

    (BOOL)webView:(UIWebView*)p_webView shouldStartLoadWithRequest:(NSURLRequest*)p_request
    navigationType:(UIWebViewNavigationType)p_navigationType
     
  3. Danneman101 thread starter macrumors 6502

    Joined:
    Aug 14, 2008
    #3
    Ok, I tried including this code:
    Code:
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    	NSURL *url = [request URL];
    	if ([[url scheme] isEqualToString:@"alert"]) {
    		
    		// Display alert
    		UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"Wazzup" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    		[myAlert show];
    		
    		return NO;
    	}
    	return YES;
    }
    
    Then I call it from my html-file using this code:
    Code:
    <a href="alert">Display alert</a>
    
    Problem is nothing happens. Im guessing thats because I really dont know WHERE I should put the ObjC-code, or if I have to add any other code as well.

    Ive tried putting it in all my .m-files, but the code doesnt work for me.

    Any ideas?
     
  4. ghayenga macrumors regular

    Joined:
    Jun 18, 2008
    #4
    First, are you sure the code is getting called? Meaning you did set the webView's delegate to be the object where you put this code?

    Second, you don't want the scheme you want the path. The following works for me with the html you posted.

    Code:
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    	NSURL *url = [request URL];
    	NSString *scheme = [url scheme];
    	
    	NSString *query = [[request URL] query];
    	NSString *URLString = [[request URL] absoluteString];
    	NSString *path = [[request URL] path];
    	
    	if ([[url path] isEqualToString:@"/alert"]) {
    		
    		// Display alert
    		UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"Wazzup" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    		[myAlert show];
    		
    		return NO;
    	}
    	return YES;
    }
    
     
  5. Danneman101 thread starter macrumors 6502

    Joined:
    Aug 14, 2008
    #5
    ghayenga:

    No, Im not sure it's called. Ive put the ObjC-code in the file that creates the WebView (called "LeafViewController.m"):

    Code:
    #import "LeafViewController.h"
    
    // Some other classes doing other stuff
    #import "AppDelegate.h"
    #import "Level3ViewController.h"
    
    @implementation LeafViewController
    
    @synthesize webView;
    
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    	NSURL *url = [request URL];
    	NSString *scheme = [url scheme];
    	NSString *query = [[request URL] query];
    	NSString *URLString = [[request URL] absoluteString];
    	NSString *path = [[request URL] path];
    	if ([[url path] isEqualToString:@"/alert"]) {
    		// Display alert
    		UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"Wazzup" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    		[myAlert show];
    		[myAlert release];
    		return NO;
    	}
    	return YES;
    }
    
    @end
    
    And this is my .h-file ("LeafViewController.h"):

    Code:
    #import <UIKit/UIKit.h>
    
    @interface LeafViewController : UIViewController <UIWebViewDelegate>
    {
        IBOutlet UIWebView *webView;
    }
    
    @property (nonatomic, retain) UIWebView *webView;
    
    @end
    
    Im not sure Im settting the webviewdelegate correctly, or if Im doing something else wrong. Unfortunately Im not very good at ObjC yet...
     
  6. ghayenga macrumors regular

    Joined:
    Jun 18, 2008
    #6
    Well you probably want to put webView.delegate = self; in your LeafViewController's viewDidLoad method then.
     
  7. Danneman101 thread starter macrumors 6502

    Joined:
    Aug 14, 2008
    #7
    ghayenga:

    So I updated the "LeafViewController.m" with the viewDidLoad()-method, but after trying it out it did not seem to be called at all. Perhaps wrong syntax?

    Code:
    #import "LeafViewController.h"
    
    // Some other classes doing other stuff
    #import "AppDelegate.h"
    #import "Level3ViewController.h"
    
    @implementation LeafViewController
    
    @synthesize webView;
    
    
    // ADDED THIS FUNCTION
    // --------------------------
    - (void)viewDidLoad {
    	[super viewDidLoad];
    	webView.delegate = self;
    }
    // ---------------------
    // END: ADDED CODE
    
    
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    	NSURL *url = [request URL];
    	NSString *scheme = [url scheme];
    	NSString *query = [[request URL] query];
    	NSString *URLString = [[request URL] absoluteString];
    	NSString *path = [[request URL] path];
    	if ([[url path] isEqualToString:@"/alert"]) {
    		UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"Wazzup" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    		[myAlert show];
    		[myAlert release];
    		return NO;
    	}
    	return YES;
    }
    
    @end
    
     
  8. ghayenga macrumors regular

    Joined:
    Jun 18, 2008
    #8
    Looks good to me.
     
  9. Danneman101 thread starter macrumors 6502

    Joined:
    Aug 14, 2008
    #9
  10. Danneman101 thread starter macrumors 6502

    Joined:
    Aug 14, 2008
    #10
    Actually, it did work once I put the webView.delegate = self; inside awakeFromNib()-function instead (it's also in the LeafViewController.m).

    Code:
    - (void)awakeFromNib
    {
    	self.webView.delegate = self;
    }
    
    However, the if-condition
    Code:
    [url path] 
    does not result in "/alert" but in a very long string ending with "/alert". I guess I can just crop it using a substring-method, but perhaps there is an easier way? Perhaps you can pass along the name or id of the controller (here the link) that called the function?

    Either way, thank you very much for your help, ghayenga :)
     
  11. Danneman101 thread starter macrumors 6502

    Joined:
    Aug 14, 2008
    #11
    This code trimmed the url to "alert":

    Code:
    NSString *pathTrimmed = [path lastPathComponent];
    
    Its a string-method that trims a path separated by "/", and gets the last bit of the path (not including the final "/").

    Just put it below the NSString *path - code.

    Again, thanks a lot for helping out - finally I can get my alerts going :D
     

Share This Page