App Browser not loading?
I want to create a custom In-App Browser to display it inside of my app.
My architecture looks something like this: subclass of UIViewController: uiviewcon which loads from its nib:
After I have instantiated uiviewcon I'm calling the following method on it:
-(void)loadrequest:(NSURLRequest *)urlrequest{
[webView loadRequest:urlrequest];
}
webview is an IBOutlet to the UIWebView in my nib. However it seems that webView is nil (I checked by if(webView)..., and I have definitely connected it in IB)
What are possible reasons for my webView not being alloced? I have implemented some methods of the UIWebViewDelegate protocol in uiviewcon (set self as delegate in viewDidLoad of uiviewcon) as well but none of these is getting called (seems reasonable since webView is nil).
How can I improve my code so that my browser finally loads something?
EDIT: My uiviewcon header:
@protocol CustomWebViewDelegate
-(void)hidecustomwebview;
@end
@interface CustomWebView : UIViewController<UIWebViewDelegate> {
UIActivityIndicatorView *spinner;
UIWebView *webView;
}
@property (nonatomic, retain) IBOutlet UIActivityIndicatorView *spinner;
@property (nonatomic, retain) IBOutlet UIWebView *webView;
@property (nonatomic,assign) id <CustomWebViewDelegate>delegate;
-(void)webViewDidStartLoad:(UIWebView *)webView;
-(void)webViewDidFinishLoad:(UIWebView *)webView;
-(void)loadrequest:(NSURLRequest *) urlrequest;
-(IBAction)hideme;
@end
Your view elements are instantiated only when required. This means that the first reference to the controller's view
property, (internally from UIKit or a reference anywhere in your code to 'self.view') triggers the process of actually creating all the elements you have in your nib.
So until the above process has occurred, your webView
property will be nil. It is most likely that you are calling loadRequest
before your view has been instantiated. The solution for your problem would be to simply change when loadRequest
is called.
So what would the right time be for calling loadRequest? There are three possibilities:
1) If you are calling loadRequest from inside CustomWebView, you can put that code in viewDidLoad
2) If you HAVE to call loadRequest from outside of CustomWebView, you can wait for the first time that you present that controller (say using presentModalViewController:animated:
or by pushing your controller onto a navigation stack) and THEN call loadRequest.
So your code could look something like:
NSURLRequest *someRequest = nil; //Assume this has some valid value
CustomWebView *myWebView = [[CustomWebView alloc] init]; //Plus other nib niceties
[self presentModalViewController:myWebView];
[myWebView loadRequest:someRequest]; //View has been created,
//loadRequest will work.
instead of what might originally have been:
NSURLRequest *someRequest = nil; //Assume this has some valid value
CustomWebView *myWebView = [[CustomWebView alloc] init]; //Plus other nib niceties
[myWebView loadRequest:someRequest]; //Your view is not created yet, loadRequest won't work.
[self presentModalViewController:myWebView];
3) If you cannot do the above, and HAVE to be able to call loadRequest at any point of time regardless of when you choose to presentModalViewController
or pushViewController
, there is always a hack to save the day :)
The hack being, just refer to self.view
in the init method of your CustomWebView, and you can be confident that the view has been setup right after 'init'. It doesn't matter how you refer to self.view
, even something like [self.view setNeedsLayout]
will do. Like I said, it doesn't matter.
This is a fairly simple problem, but I thought of laying out all the options here as it's a fairly common mistake I used to make.
Have you connected the UIWebView widget to the webView outlet in the Interface Builder window ? If not see this page on how to do it.
You should also take care when you are calling the loadRequest
method. One safe place to do it is the viewDidLoad
method, where you are guaranteed that the IBOutlet is wired.