Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development > iPhone SDK Development - Advanced Discussion

Reply
 
LinkBack Thread Tools Display Modes
Old 04-03-2009, 02:13 PM   #1 (permalink)
Taking Baby Steps...
 
Join Date: Jan 2009
Location: Denver
Posts: 37
brandons is on a distinguished road
Default UIWebView not calling webViewDidFinishLoad?

I'm having some issues with UIWebView not calling delegate methods, which is leading to the network activity indicator not stopping like it should.

Here's the basic steps that lead to an issue:
1. Initial webview loads. Activity indicator starts.
2. webview finishes loading the page. Activity indicator stops. (as expected)
3. push a navigation controller onto the stack
4. select a URL and assign a new URL for the webview
5. post notification of change & pop view controller
6. webview receives notification, activity indicator starts
7. webview finishes loading the page, but never calls webViewDidFinishLoad (or FailLoad).

Here's what I'm seeing in the log:
Code:
webViewDidStartLoad:
Webview retain count: 1
webViewDidFinishLoad:
loadURLFromRequest:
webViewDidStartLoad:
Webview retain count: 1
webViewDidFinishLoad should show up at the end but doesn't. So now I've got a loaded webpage, but a spinner that never stops spinning. Any Ideas?

Here's the code:

Code:
**in viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadURLFromRequest:) name:@"loadURLNotification" object:nil];

**sent from pushed controller
[[NSNotificationCenter defaultCenter] postNotificationName:@"loadURLNotification" object:nil];
Code:
-(void)showBookmarks:(id)sender {
	BookmarksViewController *showBookmarks = [[BookmarksViewController alloc] init];
	[[self navigationController] pushViewController:showBookmarks animated:YES];
	[showBookmarks release];
}
Code:
-(void)loadURLFromRequest:(id)sender {
	LogMethod();
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	NSString *initialURL= [defaults objectForKey:kCurrentURLKey];
	[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:initialURL]]];
	[self webViewDidStartLoad:webView];
}
Code:
-(void)webViewDidStartLoad:(UIWebView *)webView {
	LogMethod();
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView{
	LogMethod();
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
	NSString *currentURL = self.webView.request.URL.absoluteString;
	urlField.text = currentURL;
}
__________________
Still learning!

My first app - gCalWall (also now in Lite!)
brandons is offline   Reply With Quote
Old 04-05-2009, 04:01 PM   #2 (permalink)
Taking Baby Steps...
 
Join Date: Jan 2009
Location: Denver
Posts: 37
brandons is on a distinguished road
Default

Nothing? Nobody has any ideas?

It only happens if I load up another view controller and come back to this view. Driving me nuts..
__________________
Still learning!

My first app - gCalWall (also now in Lite!)
brandons is offline   Reply With Quote
Old 04-05-2009, 05:53 PM   #3 (permalink)
Crafty Veteran
 
Magic Hands's Avatar
 
Join Date: Nov 2008
Location: Memphis, TN
Age: 23
Posts: 436
Magic Hands is on a distinguished road
Send a message via Skype™ to Magic Hands
Default

This may sound trivial but are you including <UIWebViewDelegate> in your .h? If so are you setting the delegate to the class?
__________________
Magic Hands is offline   Reply With Quote
Old 04-05-2009, 06:17 PM   #4 (permalink)
Taking Baby Steps...
 
Join Date: Jan 2009
Location: Denver
Posts: 37
brandons is on a distinguished road
Default

Quote:
Originally Posted by Magic Hands View Post
This may sound trivial but are you including <UIWebViewDelegate> in your .h? If so are you setting the delegate to the class?
Yes on both accounts, but just in case I'm doing that wrong - here's that part:

Code:
@interface WebViewController : UIViewController <UIWebViewDelegate, ... >

Code:
	
webView = [[UIWebView alloc] initWithFrame:frame];
	webView.delegate = self;
	[self.view addSubview:webView];
	[self.view sendSubviewToBack:webView];
Thanks!
__________________
Still learning!

My first app - gCalWall (also now in Lite!)
brandons is offline   Reply With Quote
Old 04-05-2009, 07:37 PM   #5 (permalink)
Crafty Veteran
 
Magic Hands's Avatar
 
Join Date: Nov 2008
Location: Memphis, TN
Age: 23
Posts: 436
Magic Hands is on a distinguished road
Send a message via Skype™ to Magic Hands
Default

This is the code that I have and it works fine, so just for reference if needed.

.h

Code:
#import <UIKit/UIKit.h>


@interface className : UIViewController <UIWebViewDelegate>{
	UIWebView	*myWebView;
}

@end
.m

Code:
#import "className.h"

@implementation className

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
	UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
	self.view = contentView;
	
	CGRect webFrame = [[UIScreen mainScreen] applicationFrame];
	webFrame.origin.y = 0.0;
	myWebView = [[UIWebView alloc] initWithFrame:webFrame];
	myWebView.backgroundColor = [UIColor whiteColor];
	myWebView.scalesPageToFit = YES;
	myWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
	myWebView.delegate = self;
	[self.view addSubview: myWebView];
	[myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/"]]];
}

#pragma mark UIWebView delegate methods

- (void)webViewDidStartLoad:(UIWebView *)webView
{
	// starting the load, show the activity indicator in the status bar
	[UIApplication sharedApplication].isNetworkActivityIndicatorVisible = YES;
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
	// finished loading, hide the activity indicator in the status bar
	[UIApplication sharedApplication].isNetworkActivityIndicatorVisible = NO;
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
	// load error, hide the activity indicator in the status bar
	[UIApplication sharedApplication].isNetworkActivityIndicatorVisible = NO;
	
	// report the error inside the webview
	NSString* errorString = [NSString stringWithFormat:
							 @"<html><center><font size=+5 color='red'>An error occurred:<br>%@</font></center></html>",
							 error.localizedDescription];
	[myWebView loadHTMLString:errorString baseURL:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}


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


@end
Try this code and if it still doesn't work let me know.
__________________
Magic Hands is offline   Reply With Quote
Old 04-05-2009, 11:01 PM   #6 (permalink)
Taking Baby Steps...
 
Join Date: Jan 2009
Location: Denver
Posts: 37
brandons is on a distinguished road
Default

Yea, the code for the webView is pretty close. I had a couple minor differences (like error handling) but 98% was the same.

At this point it really looks like something to do with the navigation controller. If I don't push a navigation controller onto the stack everything works perfectly. The minute I push something onto the stack, do something in that view then pop it off the stack and come back to the webViewController - it no longer sends updates to the delegate anymore.

I've walked through it line by line with gdb and checked memory references the entire way for the webView and everything I ask the "webView" to do is being sent the same object in memory.

Its almost like I'm not getting rid of the pushed view controller and the webview is sending updates to that view instead (although I have idea how I would prove that)...

Arg.
__________________
Still learning!

My first app - gCalWall (also now in Lite!)
brandons is offline   Reply With Quote
Old 04-06-2009, 03:13 PM   #7 (permalink)
Crafty Veteran
 
Magic Hands's Avatar
 
Join Date: Nov 2008
Location: Memphis, TN
Age: 23
Posts: 436
Magic Hands is on a distinguished road
Send a message via Skype™ to Magic Hands
Default

Have you figured out this problem yet?

If not, can you post the code where you are pushing the view on with the navigation controller?
__________________
Magic Hands is offline   Reply With Quote
Old 04-06-2009, 05:04 PM   #8 (permalink)
Taking Baby Steps...
 
Join Date: Jan 2009
Location: Denver
Posts: 37
brandons is on a distinguished road
Default

In the app delegate:
Code:
navigationController = [[UINavigationController alloc] init];
WebViewController *webViewController = [[WebViewController alloc] init];
	[[self navigationController] pushViewController:webViewController animated:YES];
	[webViewController release];
The webViewController has the webView, a toolbar, the navbar and an info button. On the toolbar is stuff for navigation etc, along with a button to push a new view controller to select bookmarks. In viewDidLoad I set a notification to listen for popViewController (overkill I know) but it was something else I tried to solve this...

Code:
in viewDidLoad:
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(popViewController:) name:@"popViewControllerNotification" object:bookmarksViewController];

... other methods

-(void)showBookmarks:(id)sender {
	BookmarksViewController *bookmarks = [[BookmarksViewController alloc] init];
	[[self navigationController] pushViewController:bookmarks animated:YES];
	[bookmarks release];
}

-(void) popViewController:(id)sender {
	[self.navigationController popViewControllerAnimated:YES];
	[self loadURLFromRequest:webView];
}

-(void)loadURLFromRequest:(id)sender {
	LogMethod();
	[self shakeDetected];
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	NSString *initialURL= [defaults objectForKey:kCurrentURLKey];
	[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:initialURL]]];
	[self webViewDidStartLoad:webView];
}
The pushed view is pretty much just a standard tableview...
__________________
Still learning!

My first app - gCalWall (also now in Lite!)
brandons is offline   Reply With Quote
Old 04-06-2009, 06:00 PM   #9 (permalink)
Taking Baby Steps...
 
Join Date: Jan 2009
Location: Denver
Posts: 37
brandons is on a distinguished road
Default

Ok - don't ask me why this is now working but if I put:
Code:
webView.delegate = self;
inside the

Code:
-(void)loadURLFromRequest:(id)sender
method right above where I tell it to load the URL the webViewDidStartLoad and didFinishLoad start working again. I don't get it - I shouldn't have to do that anywhere else but where I configure it.
__________________
Still learning!

My first app - gCalWall (also now in Lite!)
brandons is offline   Reply With Quote
Old 04-06-2009, 06:37 PM   #10 (permalink)
Crafty Veteran
 
Magic Hands's Avatar
 
Join Date: Nov 2008
Location: Memphis, TN
Age: 23
Posts: 436
Magic Hands is on a distinguished road
Send a message via Skype™ to Magic Hands
Default

I think that it maybe because you are releasing the webview after you push it. I belive you need to keep it allocated.
__________________
Magic Hands is offline   Reply With Quote
Old 04-06-2009, 06:44 PM   #11 (permalink)
Taking Baby Steps...
 
Join Date: Jan 2009
Location: Denver
Posts: 37
brandons is on a distinguished road
Default

Quote:
Originally Posted by Magic Hands View Post
I think that it maybe because you are releasing the webview after you push it. I belive you need to keep it allocated.
Prior to this latest string of trying to figure this out - I wasn't releasing it. Still ended up with the same problem. Good thought though!
__________________
Still learning!

My first app - gCalWall (also now in Lite!)
brandons is offline   Reply With Quote
Old 04-06-2009, 06:54 PM   #12 (permalink)
Crafty Veteran
 
Magic Hands's Avatar
 
Join Date: Nov 2008
Location: Memphis, TN
Age: 23
Posts: 436
Magic Hands is on a distinguished road
Send a message via Skype™ to Magic Hands
Default

Yea, I was having a similar problem with MPMoviePlayerController and navigation controller. The second movie wouldn't play if I was releasing the pointer.

That is an odd way you found to fix this.
__________________
Magic Hands is offline   Reply With Quote
Old 09-15-2011, 05:26 PM   #13 (permalink)
Registered Member
 
Join Date: Sep 2011
Posts: 2
zuwhan is on a distinguished road
Default

Looks like webView is getting released and reallocated within the SDK (you don't have a full control since it was synthesized, I guess). I guess the better place to set webView.delegate is viewDidLoad (cf. iPhone SDK Tip: Firing custom events when a link is clicked in a UIWebView | dBlog.com.au).
zuwhan is offline   Reply With Quote
Old 09-15-2011, 07:12 PM   #14 (permalink)
Registered Member
 
Join Date: Sep 2011
Posts: 2
zuwhan is on a distinguished road
Default

I just realized that the better way to handle this is through Xcode (connection inspector). Simply connect the delegate of the 'Referencing Outlets' to the UIWebView. ^^
zuwhan is offline   Reply With Quote
Reply

Bookmarks

Tags
networkactivity, uiwebview

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 363
9 members and 354 guests
.Snipe, BSH, Cee Oasis, givensur, guusleijsten, HemiMG, NSString, Paul Slocum, SillyHoney
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,645
Threads: 94,111
Posts: 402,862
Top Poster: BrianSlick (7,990)
Welcome to our newest member, leighec68
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 05:23 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0