WinX Blog

Just another WordPress weblog

Posts Tagged ‘ iPhone ’

Hey everyone! I spent most of my night working on this iPhoneTether program that allows you to tether your iPhone (probably 3G only) to a computer in order to receive internet access through your phone’s connection! This is only for those who have installed iPhone OS 3.0, and works on most carriers (for example, not T-mobile Austria, apparently, unless you have the IPCC for it). It connects to Apple’s iTunes version server, and allows you to choose a carrier that it will automatically modify to allow tethering. Thanks to Erica Sadun et al (not sure who exactly was involved) for coming up with this method, and of course Steven Troughton Smith, who discovered this. Without further ado, here is the application.

http://ariweinstein.com/iPhoneTether.zip

If you liked this, feel free to donate to me at the iJailBreak site.

UPDATE 6/17/09: Since 3.0 is out to the public now, people are actually starting to use this. However, in the final iTunes, before using iPhoneTether, you will have to run the Terminal command “defaults write com.apple.iTunes carrier-testing -bool TRUE”. I will release a new version of iPhoneTether shortly that does this automagically for you. Also, a few days ago, I updated iPhoneTether to a new version that has an “Other IPCC…” button to allow you to specify your own carrier file. Good luck, and spread the word!

UPDATE 2: iPhoneTether has been updated to 1.1 with full compatability for iTunes 8.2 and 3.0 final, no Terminal hackery needed.

UPDATE 3: iPhoneTether does not currently work on iPhone OS 3.1.

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.