Loading NSURLRequest on webView from a different class.

641 Views Asked by At

I created a view controller with a webView in the storyboard called GoogleSearchController. The property for the webView was, of course, declared in the GoogleSearchController.

I am attempting to access the synthesized webView property, which is *googleWebView, within the MapViewController, so that I can append my point annotations to a google search. The output here is correct. I'm getting the appended and desired URL, but I'm failing to actually load it. At the end of the leftButtonAnnotationPressed method, you will notice I try to call loadRequest on self.classObj.googleWebView. Something is not going as it should. This is the first time I've tried to use @synthesize, and I'm open to all suggestions.

My question comes in two parts. A: am I using @synthesize as it is intended? and B: If this is the proper use, why won't my webView load the request?

GoogleSearchController.h

 @interface GoogleSearchController : UIViewController <UIWebViewDelegate>

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

 @end

GoogleSearchController.m

@synthesize googleWebView;

- (void)viewDidLoad {
    [super viewDidLoad];

    self.googleWebView = [[UIWebView alloc] init];
    self.googleWebView.delegate = self;
}

MapViewController.m

@property (nonatomic, strong) GoogleSearchController *classObj;

-(void)leftButtonAnnotationPressed:(UIButton *)sender {
[self performSegueWithIdentifier:@"googleSearch" sender:nil];
self.classObj = [[GoogleSearchController alloc] init]; <--------

MKPointAnnotation *annotation = [self.mapView.selectedAnnotations objectAtIndex:([self.mapView.selectedAnnotations count]) -1];
NSString *appendString = annotation.title;
NSString *googleString = @"http://www.google.com/search?q=";
NSString *appendedUrlString = [googleString stringByAppendingString:appendString];

if ([appendedUrlString containsString:@" "]) {
    appendedUrlString = [appendedUrlString stringByReplacingOccurrencesOfString:@" " withString:@"+"];

    NSURL *url = [NSURL URLWithString:appendedUrlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.classObj.googleWebView loadRequest:request];<------

    NSLog(@"appended string: %@", request);

}
2

There are 2 best solutions below

0
Alex Blair On BEST ANSWER

Storing the NSURLRequest in a data source seemed to be a fairly simple solution. In DataSource.h, all we did was declare a public property of type NSURLRequest *searchURL.

+(instancetype) sharedInstance;

@property (nonatomic, strong) NSURLRequest *searchURL;

The sharedInstance is going to be used for our singleton pattern, which ensures we only get one instance of our DataSource. In DataSource.m, we'll implement our sharedInstance like this: (which for the post part is text book).

+ (instancetype) sharedInstance {
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });

    return sharedInstance;
}

That's all we need to store our NSURLRequest.

Within the MapViewController we use our sharedInstance to access the NSURLRequest property from within the DataSource and set it equal to the appended NSURLRequest.

- (void) leftAnnotationButtonPressed:(UIButton *)sender {

        MKPointAnnotation *annotation = [self.mapView.selectedAnnotations objectAtIndex:([self.mapView.selectedAnnotations count]) -1];
        NSString *appendString = annotation.title;
        NSString *googleString = @"http://www.google.com/search?q=";
        NSString *appendedUrlString = [googleString stringByAppendingString:appendString];

        if ([appendedUrlString containsString:@" "]) {
            appendedUrlString = [appendedUrlString stringByReplacingOccurrencesOfString:@" " withString:@"+"];

            NSURL *url = [NSURL URLWithString:appendedUrlString];
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            [DataSource sharedInstance].searchURL = request;  <----
            NSLog(@"appended string: %@", request);
        }

        [self performSegueWithIdentifier:@"googleSearch" sender:nil];
}

All that is left is to load the webView. This can be done in view did load in the GoogleSearchController where this property resides. (which removes all of the headache).

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.googleWebView loadRequest:[DataSource sharedInstance].searchURL];
}

All we are doing here is simply calling loadRequest on our webView with the NSURLRequest that is now stored in our DataSource. And we are finished. I love this approach, and I hope anybody else reading this does to. You even get a little lesson on singletons and a data source.

7
Subbu On

@sythesize is not required/mandatory anymore. Without @synthesize iOS/XCode would automatically create an instance variable for you _[propertyName]

If your UIWebView is created in IB, you need not initialize it programatically. Make sure your webView and the ViewController IBOutlet property are connected. That should suffice.

The important reason that i can think for your request not loading is because your loading the url in a different instance than the one that is displayed in your GoogleSearchViewController

You are doing this

[self performSegueWithIdentifier:@"googleSearch" sender:nil];
self.classObj = [[GoogleSearchController alloc] init]; <--------

in the first line, you are asking storyboard to perform a segue. So, story board will create an instance of the view controller with views and all the subviews and display.

In the second line, you are creating your own instance of the view controller.. Who is displaying it? -- No one.

Your loading the url in the wrong instance.

Ok now, how do i gain access to the view controller that is being displayed?

Xcode/iOS gives you an option to do that with prepareForSegue you can access the VC and the webview like shown below to load the request.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"googleSearch"]){
        GoogleSearchViewController *vc = nil;
        if([segue.destinationViewController isKindOfClass:[UINavigationController class]]){
            UINavigationController *navVC = (UINavigationController *)segue.destinationViewController;
            vc = (GoogleSearchViewController *)navVC.viewControllers[0];
        }else{
            vc = segue.destinationViewController;
        }
        if(vc){
            NSURL *url = [NSURL URLWithString:appendedUrlString];
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            [vc.googleWebView loadRequest:request];

        }
    }

}

Would be interested to know if this worked for you