How to create an iPhone in-app web browser
I have been looking for a while for an in-app browser without finding exactly what I wanted. I eventually figure that the in-app browser from the three20 library had exactly the features that I wanted : 1) basic navigation, 2)ability to add the browser to my navigation controller and 3) option to open web links in Safari for better surf if needed.
I slightly changed the code so no need to add the three20 library to your project. I also added a source that you can find HERE. The webview is now called from a UIButton from the Favorite screen.
URL is passed to the webView controller using the – (id)initWithURLPassed:(NSString *)initURL method.
UPDATE: Made a change in dealloc method.
// // webView.h // Created by Pierre Addoum on 2/17/10. // myFirstiPhoneapplication.com @interface webViewController : UIViewController{ UIWebView* _webView; UIToolbar* _toolbar; UIBarButtonItem* _backButton; UIBarButtonItem* _forwardButton; UIBarButtonItem* _refreshButton; UIBarButtonItem* _stopButton; UIBarButtonItem* _activityItem; NSURL* _loadingURL; NSString *stringURL; } @property(nonatomic,readonly) NSURL* URL; //@property(nonatomic,retain) UIView* headerView; @property(nonatomic,retain) NSString *stringURL; - (id)initWithURLPassed:(NSString *)initURL; - (void)openURL:(NSURL*)URL; - (void)openRequest:(NSURLRequest*)request; @end
// webView.m
// Created by Pierre Addoum on 2/17/10.
// myFirstiPhoneapplication.com
#import "webViewController.h"
#define RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; }
@implementation webViewController
@synthesize stringURL;
///////////////////////////////////////////////////////////////////////////////////////////////////
- (id)initWithURLPassed:(NSString *)initURL {
if (self = [super init]) {
NSLog(@"string URL %@ ",initURL);
if([initURL isEqualToString:@""]){
[self openURL:[NSURL URLWithString:@"http://www.agwine.com"]];
self.hidesBottomBarWhenPushed = YES;
} else{
[self openURL:[NSURL URLWithString:initURL]];
self.hidesBottomBarWhenPushed = YES;
}
}
return self;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)backAction {
[_webView goBack];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)forwardAction {
[_webView goForward];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)refreshAction {
[_webView reload];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)stopAction {
[_webView stopLoading];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)shareAction {
UIActionSheet* sheet = [[[UIActionSheet alloc] initWithTitle:@"" delegate:self
cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil
otherButtonTitles:@"Open in Safari", nil] autorelease];
[sheet showInView:self.view];
}
- (void)dealloc {
RELEASE_SAFELY(_loadingURL);
RELEASE_SAFELY(_webView);
RELEASE_SAFELY(_toolbar);
RELEASE_SAFELY(_backButton);
RELEASE_SAFELY(_forwardButton);
RELEASE_SAFELY(_refreshButton);
RELEASE_SAFELY(_stopButton);
RELEASE_SAFELY(_activityItem);
RELEASE_SAFELY(stringURL);
[super dealloc];
}
- (void)loadView {
[super loadView];
////WEBVIEW////////////////////
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,320,460)];
_webView.delegate = self;
_webView.autoresizingMask = UIViewAutoresizingFlexibleWidth
| UIViewAutoresizingFlexibleHeight;
_webView.scalesPageToFit = YES;
[self.view addSubview:_webView];
////SPINNER///////////////////
UIActivityIndicatorView* spinner = [[[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite] autorelease];
[spinner startAnimating];
////Button///////////////////
_activityItem = [[UIBarButtonItem alloc] initWithCustomView:spinner];
_backButton = [[UIBarButtonItem alloc] initWithImage:
[UIImage imageNamed:@"backIcon.png"]
style:UIBarButtonItemStylePlain target:self action:@selector(backAction)];
_backButton.tag = 2;
_backButton.enabled = NO;
_forwardButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"forwardIcon.png"] style:UIBarButtonItemStylePlain target:self action:@selector(forwardAction)];
_forwardButton.tag = 1;
_forwardButton.enabled = NO;
_refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemRefresh target:self action:@selector(refreshAction)];
_refreshButton.tag = 3;
_stopButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemStop target:self action:@selector(stopAction)];
_stopButton.tag = 3;
UIBarButtonItem* actionButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemAction target:self action:@selector(shareAction)] autorelease];
UIBarItem* space = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease];
_toolbar = [[UIToolbar alloc] initWithFrame:
CGRectMake(0, 460 - 44, 320, 44)];
_toolbar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
_toolbar.tintColor = [UIColor blackColor];
_toolbar.items = [NSArray arrayWithObjects:
_backButton, space, _forwardButton, space, _refreshButton, space, actionButton, nil];
[self.view addSubview:_toolbar];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)viewDidUnload {
[super viewDidUnload];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)viewWillDisappear:(BOOL)animated {
// If the browser launched the media player, it steals the key window and never gives it
// back, so this is a way to try and fix that
[self.view.window makeKeyWindow];
[super viewWillDisappear:animated];
_webView.delegate = nil;
}
#pragma mark -
#pragma mark UIWebViewDelegate
///////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request
navigationType:(UIWebViewNavigationType)navigationType {
RELEASE_SAFELY(_loadingURL);
_loadingURL = [request.URL retain];
_backButton.enabled = [_webView canGoBack];
_forwardButton.enabled = [_webView canGoForward];
return YES;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)webViewDidStartLoad:(UIWebView*)webView {
self.title = @"Loading...";
if (!self.navigationItem.rightBarButtonItem) {
[self.navigationItem setRightBarButtonItem:_activityItem animated:YES];
}
UIBarButtonItem* actionButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemAction target:self action:@selector(shareAction)] autorelease];
UIBarItem* space = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease];
_toolbar.items = [NSArray arrayWithObjects:
_backButton, space, _forwardButton, space, _stopButton, space, actionButton, nil];
_backButton.enabled = [_webView canGoBack];
_forwardButton.enabled = [_webView canGoForward];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)webViewDidFinishLoad:(UIWebView*)webView {
RELEASE_SAFELY(_loadingURL);
self.title = [_webView stringByEvaluatingJavaScriptFromString:@"document.title"];
if (self.navigationItem.rightBarButtonItem == _activityItem) {
[self.navigationItem setRightBarButtonItem:nil animated:YES];
}
UIBarButtonItem* actionButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemAction target:self action:@selector(shareAction)] autorelease];
UIBarItem* space = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemFlexibleSpace target:nil action:nil] autorelease];
_toolbar.items = [NSArray arrayWithObjects:
_backButton, space, _forwardButton, space, _refreshButton, space, actionButton, nil];
_backButton.enabled = [_webView canGoBack];
_forwardButton.enabled = [_webView canGoForward];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error {
RELEASE_SAFELY(_loadingURL);
[self webViewDidFinishLoad:webView];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark UIActionSheetDelegate
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)actionSheet:(UIActionSheet*)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
[[UIApplication sharedApplication] openURL:self.URL];
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (NSURL*)URL {
return _loadingURL ? _loadingURL : _webView.request.URL;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)openURL:(NSURL*)URL {
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:URL];
[self openRequest:request];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)openRequest:(NSURLRequest*)request {
self.view;
[_webView loadRequest:request];
}
@end
Could you please provide the source code for the application, the copied code seems to be broken.
I’ll see what I can do for you.
Pierre
John, I slightly modified the code and added the source code.
Not bad article, but I really miss that you didn’t express your opinion, but ok you just have different approach
Hi John, Thanks for the useful code. May I use your code and modify it for my will?
@Ishay: Actually my name is Pierre
You can use this piece of code the way you want.
Cheers!
Pierre
could you provide a download link for the whole project?
Link to the project is in the post !
p.
do you have any idea why is crashing coming back from webview?
is it happening only to me?
gp,
My mistake, move [super dealloc] to the end of the -(void) dealloc method like that :
- (void)dealloc {
RELEASE_SAFELY(_loadingURL);
RELEASE_SAFELY(_webView);
RELEASE_SAFELY(_toolbar);
RELEASE_SAFELY(_backButton);
RELEASE_SAFELY(_forwardButton);
RELEASE_SAFELY(_refreshButton);
RELEASE_SAFELY(_stopButton);
RELEASE_SAFELY(_activityItem);
RELEASE_SAFELY(stringURL);
[super dealloc];
}
It should work fine.
P.
Your site is nice! Generally whenever i visit blogs, I simply run into shit, but this occassion I became really surprised when I got your blog containing great information. Thanks mate and keep this effort up.