1

for the past couple of days I've been looking into UIWebViews and Delegates and I'm totally confused. I want to create a storyboard view controller which contains a web view. When a button is clicked in the web view I want to fire some code in the view controller as per the answer to this:

How to invoke Objective C method from Javascript and send back data to Javascript in iOS?

However I'm confused as to how to set up my delegate (I'm confused as to what even a delegate is to be honest, is it the webview in relation to the viewcontroller?). I've been reading and watching some tutorials but I don't really understand the process and I don't think I'm doing it right. Here's what I have so far.

MyViewController.h

#import <UIKit/UIKit.h>

@protocol MyViewControllerDelegate;

@interface MyViewController : UIViewController
@property (nonatomic, weak) id<MyViewControllerDelegate> delegate;

@property (strong, nonatomic) IBOutlet UIWebView *MyWebView;

@end

@protocol MyViewControllerDelegate <NSObject>

-(bool)myWebView:(UIWebView*)myWebView
shouldStartLoadWithRequest:(NSURLRequest*)request
                  navigationType:(UIWebViewNavigationType)navigationType;

@end

MyViewController.m

#import "MyViewController.h"

@interface MyViewController ()
@end

@implementation MyViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [_MyWebView setDelegate:self];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewWillAppear:(BOOL)animated
{   
}

@end

I'm not really sure where the implementation for:

-(bool)myWebView:(UIWebView*)myWebView
shouldStartLoadWithRequest:(NSURLRequest*)request
                  navigationType:(UIWebViewNavigationType)navigationType;

should go.

If anyone could help it would be greatly appreciated.

Community
  • 1
  • 1
Alec Gamble
  • 441
  • 3
  • 6
  • 16

2 Answers2

1

Delegates provides the way of communication on different events. Like in case of above method when you load webview with the given url.

- (void)viewDidLoad {
    [super viewDidLoad];
    [_MyWebView setDelegate:self];
    NSString *urlString = @"http://google.com";
    //Create a URL object.
    NSURL *url = [NSURL URLWithString: urlString];
    //URL Request Object
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    //Load the request in the UIWebView.
    [_MyWebView loadRequest:requestObj];
}

Now using delegates webview will be communicating with your controller. When webview will be begin loading a new frame it will call the above method mentioned by you. The purpose of this method is taking permission from you either it should load data or not? In particular case if you don't want to load webView you can return no in this method.

There are certain other delegate method which update you about certain stages like if webview has loaded the content of the url mentioned by you it will tell the controller by calling this method.

- (void)webViewDidFinishLoad:(UIWebView *)webView{
 //if you want to do anything else after loading the content of webview you can write code here. for example after loading the content you want to show a button on controller you can show it here. 
}

In case webview failed to load the webpage or frame because of low internet connection or invalid url or anything. It tells the controller by calling another delegate method which is.

- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error{

}
Shehzad Ali
  • 1,846
  • 10
  • 16
  • Thank you for your answer, I don't want to load any of the views but I want to be able to call some objective-c functionality and then segue to my next view. I'm just confused as to how to actually implement this in the code. – Alec Gamble May 04 '16 at 11:28
  • Why are you using UIWebView? What are you loading in it? Segues can be implemented by using single line. Assuming that you have linked your current viewController with next ViewController using segue and you have its identifier. `[self performSegueWithIdentifier:@"NextViewSegueIdentifier" sender:self];` – Shehzad Ali May 04 '16 at 11:34
  • I'm using the UIWebView for cross-platform content and for convenient content update via the web application. But I then need to be able to segue to a view with a camera overlay but it needs to take some information from the button which is pressed in the web view. – Alec Gamble May 04 '16 at 11:38
  • can you share what kind of information you need to get from that button? Is it the next link you need to open or it's something else. – Shehzad Ali May 04 '16 at 11:58
  • I need to get a url to an image for a splash screen and then I need to load a camera with a custom overlay based on the button and then I need to open a new web view with content based on that. – Alec Gamble May 04 '16 at 12:01
  • `- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSLog(@"%@", request.URL) return YES; }` – Shehzad Ali May 04 '16 at 12:29
1

First of all, you need to understand the concept of delegation. A delegate can be an object which can react on behalf of another object when an event or an action encounters within that object.

For example, you can have a UIViewController which has a UITbleView inside it. The UIViewController can have a UITableViewDelegate. In this case, all UITableViewDelegate methods (heightForRow, ViewForFooter, didSelectRowAtIndexPath, ….) can be implemented via UIViewController. So for example when a cell is selected (didSelectRowAtIndexPath), UIViewController can see what cell is selected and decide what to do with that selection.

In your case, you have an instance of UIWebView in your UIViewController. Your UIViewController will need to be a delegate of the UIWebView.

@interface UIViewController () <UIWebViewDelegate>

and then you set the delegate of your UIWebView property to yourself in viewDidLoad.

[self.webView setDelegate:self];

Now you can call the delegate methods within your viewController.

-(bool)myWebView:(UIWebView*)myWebView shouldStartLoadWithRequest (NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType;

in your .m file of your view controller and decide what you wanna do with the information you receive from the web view.

Nelly v
  • 229
  • 1
  • 12
  • That's a really helpful explanation! So in my example is there stuff I don't need in there? – Alec Gamble May 04 '16 at 11:23
  • and you're saying that in the .m file I just create a function within the `@implementation` which is `-(bool)myWebView:(UIWebView*)myWebView shouldStartLoadWithRequest (NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{ ... }`? – Alec Gamble May 04 '16 at 11:26
  • You need to remove **@property (nonatomic, weak) id delegate;** and just add **@interface MyViewController : UIViewController ** You can then implement any methods of UIWebViewDelegate. You can see a list of these methods by holding down command and click on UIWebViewDelegate name on Xcode. Please accept my answer if it was helpful for you. – Nelly v May 04 '16 at 11:31
  • so if there were multiple webviews in the view controller would this take control of the actions on both of their behalf? – Alec Gamble May 04 '16 at 11:34
  • As long as you would set the delegate of them all to yourself, yes. You would then differentiate in the delegate methods to see which webView is being called: if (self.webview1) { //then do this ....} else { //do otherwise} – Nelly v May 04 '16 at 11:41