View Full Version : Following website, but code isn't working (tracking progress of a WebView)
MythicFrost
Sep 19, 2011, 11:47 PM
Hey,
I'm following this website and trying to get the code working in my app: http://fei263.blog.163.com/blog/static/92793724200952684731442/
(I downloaded the headers from the above site, added them into my project and have imported them in my .m file)
This is my code:
- (void)viewDidLoad {
[super viewDidLoad];
test = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
test.scalesPageToFit = YES;
test.delegate = self;
[self.view addSubview:test];
WebView *coreWebView = [[test _documentView] webView];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(progressEstimateChanged:) name:@"WebViewProgressEstimateChangedNotification" object:coreWebView];
NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[test loadRequest:urlRequest];
}
- (void)progressEstimateChanged:(NSNotification*)theNotification {
NSLog(@"The progress: %@", [[theNotification object] estimatedProgress]);
if ((int)[[theNotification object] estimatedProgress] == 1) {
NSLog(@"The progress is finished");
}
}
I am able to run the code, but I never see any log notifications. I wasn't able to do add the frameworks requested (WebKit.framework and WebCore.framework) as I couldn't find them however I don't receive any compiler errors, only one repeated warning which doesn't seem relevant, but here it is nonetheless:
Declaration of 'struct __GSEvent' will not be visible outside of this function
ianray
Sep 20, 2011, 12:25 AM
Place a breakpoint on (or NSLog in) viewDidLoad. Is it called?
MythicFrost
Sep 20, 2011, 12:31 AM
Place a breakpoint on (or NSLog in) viewDidLoad. Is it called?
Thanks for your reply,
Yes, it is called.
ianray
Sep 20, 2011, 02:11 AM
You are using a string literal @"WebViewProgressEstimateChangedNotification" instead of the string 'WebViewProgressEstimateChangedNotification'.
This is the problem.
See:
http://trac.webkit.org/browser/trunk/Source/WebKit/mac/WebView/WebView.mm?rev=95474#L424
NSString *WebViewProgressEstimateChangedNotification = @"WebProgressEstimateChangedNotification";
MythicFrost
Sep 20, 2011, 02:31 AM
Thank you, the notification is being sent now and it is working.
I have another question to anyone whom might know the answer: when I load apple.com it never gets to 1.0? It finishes at ~0.9 (90%).
How would I handle that? Perhaps other websites will only show 0.2? Or is it safe to assume that everything will reach at least 0.7? Any thoughts on this?
ianray
Sep 20, 2011, 02:47 AM
Thank you, the notification is being sent now and it is working.
:)
NSLog(@"The progress: %@", [[theNotification object] estimatedProgress]);
How are you logging the estimatedProgress? The above code should crash because it treats the double as an object.
when I load apple.com it never gets to 1.0? It finishes at ~0.9 (90%).
Have you implemented UIWebViewDelegate protocol? Is webViewDidFinishLoad called?
MythicFrost
Sep 20, 2011, 06:09 AM
:)
NSLog(@"The progress: %@", [[theNotification object] estimatedProgress]);
How are you logging the estimatedProgress? The above code should crash because it treats the double as an object.
That did happen and I managed to figure it out. I replaced %@ with %f.
Have you implemented UIWebViewDelegate protocol? Is webViewDidFinishLoad called?
Well, yes I have. I'm intentionally avoiding webViewDidFinishLoad because it's inaccurate. I'm going to use the estimatedProgress to track the progress, and also for when it's finished. (So I hope, anyway).
EDIT:
I added this variable and got the proper string content from the website you linked:
NSString *WebViewProgressFinishedNotification = @"WebProgressFinishedNotification";
And changed the notification to use it instead:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(progressEstimateChanged:) name:webViewProgressFinishedNotification object:coreWebView];
And then I added a simple NSLog notification to test if it fired or not, and it didn't. Do you have any idea why it didn't fire?
ArtOfWarfare
Sep 20, 2011, 06:25 AM
I'm intentionally avoiding webViewDidFinishLoad because it's inaccurate. I'm going to use the estimatedProgress to track the progress, and also for when it's finished. (So I hope, anyway).
My understanding is that everything associated with seeing progress with webpages loading is inaccurate just because there could always be scripts that suddenly say more stuff needs to load. Or something like that.
ianray
Sep 20, 2011, 06:29 AM
And then I added a simple NSLog notification to test if it fired or not, and it didn't. Do you have any idea why it didn't fire?
Does it even compile? Hint: look at the capitalization of the notification variable name in the code you pasted...
jiminaus
Sep 20, 2011, 06:32 AM
NSString *WebViewProgressFinishedNotification = @"WebProgressFinishedNotification";
I think you've mistyped the literal. Should it not be @"WebViewProgressFinishedNotification"?
MythicFrost
Sep 20, 2011, 06:40 AM
My understanding is that everything associated with seeing progress with webpages loading is inaccurate just because there could always be scripts that suddenly say more stuff needs to load. Or something like that.
That's not the type of accuracy I'm talking about, webViewDidFinishLoad fires multiple times. And the estimation parameter I'm using seems reasonably accurate, I'm surprised.
Does it even compile? Hint: look at the capitalization of the notification variable name in the code you pasted...
Yes, it does. I fixed that capitalisation, I'm not sure how I posted it though, haha. Thanks.
I think you've mistyped the literal. Should it not be @"WebViewProgressFinishedNotification"?
I don't think so, I got the literal off a website posted above. I originally wrote it the same way for the estimate, but that was wrong and ~webProgressEstimate... was the correct way of writing it.
>>>>>>>
Okay, I've come to a realisation. The webViewProgressStartedNotification operates the same as webViewDidStartLoad, although the documentation for the former is clearer and states:
Posted by a WebView object when a load begins, including a load that is initiated in a subframe. The notification object is the WebView that began loading. This notification does not contain a userInfo dictionary.
The same is true of webViewProgressEstimateChangedNotification. It also seems to run for subframes. I suspected this after talking with someone on another forum and maybe I think even prior to that (along those lines, anyway).
From what I can determine with webViewProgressEstimateChangedNotification is that, after loading hulu.com, it loads the main web page first which takes about ten seconds (notifying me with the estimate completed) and then finally "Finished", and then it does the same twice more but really quickly (in less than 5 ms each time).
So, I'm tossing up how to determine when a subframe is loading and how I can prevent it? I thought perhaps doing it by the date, which might work but I'm at a loss at the moment.
Would appreciate any insight! Cheers!
ianray
Sep 20, 2011, 06:41 AM
I think you've mistyped the literal. Should it not be @"WebViewProgressFinishedNotification"?
No, see: http://trac.webkit.org/browser/trunk/Source/WebKit/mac/WebView/WebView.mm?rev=95474#L425
So, I'm tossing up how to determine when a subframe is loading and how I can prevent it? I thought perhaps doing it by the date, which might work but I'm at a loss at the moment.
Some people have had luck with simply counting calls to webViewDidStartLoad & webViewDidFinishLoad. See: http://stackoverflow.com/questions/908367/uiwebview-how-to-identify-the-last-webviewdidfinishload-message
Good luck :)
jiminaus
Sep 20, 2011, 06:43 AM
No, see: http://trac.webkit.org/browser/trunk/Source/WebKit/mac/WebView/WebView.mm?rev=95474#L425
Ahh, that's unfortunate that the constant is different to the literal.
MythicFrost
Sep 20, 2011, 09:00 AM
Some people have had luck with simply counting calls to webViewDidStartLoad & webViewDidFinishLoad. See: http://stackoverflow.com/questions/908367/uiwebview-how-to-identify-the-last-webviewdidfinishload-message
Good luck :)
It's not accurate I'm afraid, sometimes the calls are serial which means it'll run multiple times.
Oi! This is so complex, one would think it'd be easy to determine when a web page is finished loading...!
If only I could determine from the notification sent to the method (progressMethodEstimate) whether it is a subframe or not... :eek:
Thanks for your help everyone!
EDIT: Is there any method/property in NSURLRequest or NSURL that I could use to check whether it is a subframe or not? Perhaps something that I could use javascript in tangent with? Just throwing out idea's here.
vBulletin® v3.8.6, Copyright ©2000-2013, Jelsoft Enterprises Ltd.