iPhone UIWebView Estimated Progress

In the iPhone SDK, web views are accomplished using UIKit’s UIWebView class. Instead of allowing you direct access to WebKit’s WebView class, UIWebView handles everything for you and allows some control of the view. One thing Apple left out in UIWebView, for reasons unknown, is progress. If you want to have a progress bar in your web view so people know that something’s actually happening (in addition to the web activity indicator in the status bar), this is basically the only way to do it.

NOTE: This method DOES use what Apple considers to be a private framework. That said, there are a few applications in the App Store using this, and this method is slightly unlikely to change, because WebView is not an iPhone-specific thing, and if Apple changed it, tons of Mac applications would no longer work as well.

NOTE 2: In this post, I will talk about two classes. UIWebView, and WebView. These are NOT the same class. UIWebView is the public, official web view, and WebView is the private, internal WebKit web view. WebView has the estimated progress, but we want to use UIWebView as the main view so we don’t have to reinvent the wheel in a lot of ways.

So, say you have a UIWebView called officialSDKWebView. We want to extract the main WebView from that to get the progress. To do so, we have to use another internal class called UIWebDocumentView. From there, we can get the WebView easily. Here’s the code:


UIWebDocumentView *documentView = [officialSDKWebView _documentView];
WebView *coreWebView = [documentView webView];

Well, that was pretty easy, huh? But let’s make it easier, and do it in one line:

WebView *coreWebView = [[officialSDKWebView _documentView] webView];

Of course, the compiler won’t like this, as we don’t have header files… I uploaded the necessary header files to reduce the error count to zero (as well as some useless stuff), and you can download it here. Add these with

#import "WebView.h"
#import "UIWebDocumentView.h"
in your header file.
But wait, the compiler still isn’t happy… So we need to add two frameworks to the project. You can do this by right-clicking Frameworks in the left pane of Xcode, and choosing Add -> Existing Frameworks. Navigate to /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.sdk/System/
Library/PrivateFrameworks/
and then add WebKit.framework and WebCore.framework.
Of course, this is completely useless if we can’t figure out when the progress has changed, but we can fix that as well.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(progressEstimateChanged:) name:WebViewProgressEstimateChangedNotification object:coreWebView];

We’re now subscribed to progress change events, and it will run the method progressEstimateChanged: as soon as there is an update. So, let’s write a progressEstimateChanged method.


- (void)progressEstimateChanged:(NSNotification*)theNotification {
	// You can get the progress as a float with
	// [[theNotification object] estimatedProgress], and then you
	// can set that to a UIProgressView if you'd like.
	// theProgressView is just an example of what you could do.

	[theProgressView setProgress:[[theNotification object] estimatedProgress]];
	if ((int)[[theNotification object] estimatedProgress] == 1) {
		theProgressView.hidden = TRUE;
		// Hide the progress view. This is optional, but depending on where
		// you put it, this may be a good idea.
		// If you wanted to do this, you'd
		// have to set theProgressView to visible in your
		// webViewDidStartLoad delegate method,
		// see Apple's UIWebView documentation.
	}
}

And, there we are! That should do it. If you have any questions, or if I made a mistake in my code, feel free to make a comment. If you need an example, I’ll be posting an Xcode project probably at some point.

Popularity: 27% [?]

This entry was posted in iPhone SDK and tagged , , , , , , . Bookmark the permalink.

35 Responses to iPhone UIWebView Estimated Progress

  1. Alex Curylo says:

    Thanks a whack, dude. I needed to sort out how to call -setCustomUserAgent: on the phone, and this appears to do the trick nicely!

  2. yile says:

    thx, man!
    I just wanna try them out~!

  3. Pingback: UIWebView internals at Under The Bridge

  4. Ivan says:

    Thanks! Good stuff!

  5. Dirk says:

    Hi there,
    I am trying to get your code up and running right now…
    Can you please tell me where the notification name WebViewProgressEstimateChangedNotification is declared ?

    I still get the error “WebViewProgressEstimateChangedNotification” undeclared!

    I am using WebKit.framework and WebCore.framework of the 2.2.1 iPhone SDK version be be found in
    /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/PrivateFrameworks/

    Thanks for good work !

    Dirk

    BTW: Will Apple still certify an application making use of this private framework ?

  6. Tung Do says:

    I have the same problem with “WebViewProgressEstimateChangedNotification” undeclared. Can’t find out how to fix it. :(

  7. Steven says:

    If you replace the line
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(progressEstimateChanged:) name:WebViewProgressEstimateChangedNotification object:coreWebView];
    with
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(progressEstimateChanged:) name:@”WebProgressEstimateChangedNotification” object:coreWebView];
    this seems to fix the problem.

  8. srw says:

    Good stuff, what’s is interesting is that a UITextView is also embedding a UIWebView.

  9. Dirk says:

    @”WebProgressEstimateChangedNotification”
    This indeed helps, thanks!
    But again: Will Apple certify (and then sell using the AppStore) an application making use of this private Framework?

  10. Dirk says:

    >Good stuff, what’s is interesting is that a UITextView
    >is also embedding a UIWebView.
    What exactly do you mean by this? Why do you want incorporate a WebView inside a TextView ? What for? Please explain!

  11. mitschi says:

    apple does not allow the use of this:

    > “3.3.1 Applications may only use Published APIs in the manner
    > prescribed by Apple and must not use or call any unpublished or private
    > APIs. ”
    >
    > The non-public API that is included in your application comes from the
    > following private Apple frameworks – WebKit.framework.

  12. Darcy says:

    I’ve tried everything and I can’t get this to work.
    No errors, it’s just the progress bar doesn’t change and the “progressEstimateChanged” method is never called.

  13. JaneRadriges says:

    Hi, very nice post. I have been wonder’n bout this issue,so thanks for posting

  14. Eric says:

    Hi guys,
    Put this line in your source code.
    extern NSString *WebViewProgressEstimateChangedNotification;

  15. will this work with the 3GS?

  16. SiDart says:

    ??????? ? ?????????, ???????? ?? ?????

  17. Koshan says:

    ????? ????? ???????? ? ?????????, ??? ???????????

  18. paramvir says:

    hi

    [[webView _documentView] webView] is not working with ios5 sdk
    can u resolve this issue

  19. paramvir says:

    hi
    asked question little early its solved
    just need to use double and comparing with 0

  20. Pingback: How to find last load of UIWebView(Ready State 4) - feed99

  21. Matrix-Avatar says:

    Hello,I just wana to get a demo that show the loading percent on the UIWebView~~many thanks

  22. Pingback: How to find last load of UIWebView(Ready State 4)

  23. shahid iqbal says:

    nice

  24. murali says:

    if ((int)[[theNotification object] estimatedProgress] == 1) …..this condition was never satisfying ..i mean estimatedprogress never come to 1…
    So how can i hide progressbar

  25. Yoshioka Tsuneo says:

    I just rejected from iOS AppStore because of using non-public “_documentView” API.

  26. paleo diet says:

    Great website. Thank a lot for posting that. I will check back to find out more and inform my neighbors about your posting.

  27. It also allows you to capture & store videos while you are
    out for a tour or picnic with friends. Uncooked ginkgo
    biloba seeds have shown some small levels of toxins, so if you prefer the seeds it is advised to cook them prior to ingestion.
    if you’re under 120 lbs, unless you’re really short you are NOT overweight.

    My web blog: http://www.familydentalcentre.com

  28. Christie says:

    The report first appeared on Thursday, spoiling Apple’s Valentine’s Day.
    Some time ago, Control device included a brand new services
    named Vapor Cloud Assist. They will only consider Paypal, and that generally is
    a pain, but it will let the user be reassured that they’re supported and struggling with an honest vendor.

  29. Looking for information on Paleo Diet Cooking?
    Visit my website.

  30. 30MinutePR.com Took my Cash But Didn’t Deliver Anything!
    Refuses to Refund Income

  31. This is surely an old saying that work with out play
    make jack a dull boy. Over the past few years disabled living awareness
    and action is still acknowledged all over the country globe ensuring the security, well-being and health of disabled persons.
    Light shades seem elegant but get dirty very quickly with children around.

    Also visit my blog post :: Fix My credit

  32. Well, we were holding the talking of earlier also now
    HCG an extremely to was the complete fact your manner in which toward a farther healthier lifestyle.
    To administer the daily feature 125 to 200 IU in the hormone you’ve got two solutions to choose
    from the intravenous injections along with the HCG drops.
    Thus if you need an effortless approach to shed weight, you should get HCG diet recipes online
    or from any trustworthy suppliers.

  33. Elena says:

    Because the diet program was around for thousands of
    years prior to the development of agriculture, Atkins figured that
    the reason many people had difficulty shedding pounds and keeping the weight off is that were eating up
    against the way our gastrointestinal system is set up.
    This way you will be acquiring low carbohydrate diets recipes that look fabulous, sample terrific and possess the added gain to be good for you.

    On this website, you will quickly realize recipes for mushroom bruschetta, creamy seafood pasta, honey-lemon chicken
    with almonds, cheeseburgers, classic hot dogs, minestrone soup,
    Greek shrimp with feta, antipasto pasta salad, and lemon sorbet with strawberry sauce.

    Check out my blog post – but to let mortgages (Elena)

  34. It is sad if what Yoshioka Tsuneo said is accurate.
    What would be the reason behind Apple not allowing people posting applications with private libraries? The public libraries are fine but their limitations are crazy sometimes.
    Thank you for your posting!

    P/D: I would add a captcha box and a mathematical equation boxes in the submit form so you can prevent spammers to fill the comments with their crappy advertising. If you are using word and you wish to know which plugins I use let me know.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>