Find the best blogs in your city, Maybe you are one of them!
So you want an OpenGL ES iOS app, but hate dealing with Interface Builder? Not a problem. I’ll walk you through the steps necessary to get rid of IB from your project while maintaining its pre-rendered functionality.
Let’s begin!
When you create a new OpenGL ES project in XCode it will generate several files for you, however, we’re only going to be concerning ourselves with EAGLView.m.
In your Info.plist file, be sure and remove the Main nib file basename line that loads the MainWindow.nib file. You might as well remove the MainWindow.nib file while you’re at it. In order for your application to launch without MainWindow.nib we’ll need to modify our main.m file.
Open up main.m and import your AppDelegate file. In the UIApplicationMain function, change the fourth parameter from nil to the name of your AppDelegate’s class as shown.
#import "ExampleAppDelegate.h"
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, @"ExampleAppDelegate");
[pool release];
return retVal;
}
The EAGLView.m Fix
Next we need to change EAGLView.m to load via code instead of the nib. Initially, EAGLView.m is created when the nib is unarchived and initWithCoder is called on the EAGLView class. All we need to do is change the code from initWithCoder to initWithFrame.
// The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
// - (id) initWithCoder:(NSCoder*)coder {
// if ((self = [super initWithCoder:coder])) {
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// ...
Loading and initializing the window and EAGLView programmatically
We’re nearly done. All that’s left is to get rid of our IBOutlets and initialize our views in the AppDelegate. Open up your application’s AppDelegate header file and remove any occurrances of IBOutlet.
//@property (nonatomic, retain) IBOutlet UIWindow *window;
//@property (nonatomic, retain) IBOutlet EAGLView *glView;
@property (nonatomic, retain) UIWindow *window;
@property (nonatomic, retain) EAGLView *glView;
Now open up your application’s AppDelegate implementation file and bring your attention to the applicationDidFinishLaunching method. Here we allocate and initialize our views and make sure they’re visible on screen. We’ll need to initialize the window and the glView, make the glView a subview of window, and finally make the window visible. Here’s the code:
- (void) applicationDidFinishLaunching:(UIApplication *)application
{
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
glView = [[EAGLView alloc] initWithFrame:window.frame];
[window addSubview:glView];
[window makeKeyAndVisible];
[glView startAnimation];
}
And there you have it! A bonified nibless OpenGL ES iOS application literally at the palm of your hands. Feel free to catch me on twitter if you have any questions.
This is a rebound from my last post on method swizzling.
If you happened to use my brilliant technique hack to render an “in app Safari” for detected URLs in UITextViews, then you might be in some trouble. I’m almost certain that Apple won’t let your app past the app store approval process. I pretty much knew this coming in, but it’s still a pretty cool idea.
With that said, I should probably provide a better solution that will make it through Apple HQ. This is currently the best solution I’ve found to handle this, which also happens to be the same solution used in the Twitter iPhone app.
MSTextView was designed to be a drop in replacement for UITextView. It automatically parses URLs and provides a callback via protocol to handle the URL tapped allowing the user to do whatever with the URL—probably opening the URL in a custom web view. It’s pretty easy to use, take a look at the code.
Using MSTextView
- (void) viewDidLoad {
NSString *sample = @"Check out my GitHub page http://github.com/marksands or go to http://google.com instead. \
Optionally, try out a news site such as http://yahoo.com or http://cnn.com";
MSTextView *textView = [[MSTextView alloc] initWithFrame:CGRectMake(10, 10, 310, 480)];
textView.delegate = self;
textView.text = sample;
[self.view addSubview:textView];
[textView release];
}
#pragma Delegate
- (void) handleURL:(NSURL*)url
{
WebViewController *webview = [[WebViewController alloc] initWithURL:url];
[self.navigationController pushViewController:webview animated:YES];
[webview release];
}


If you like what you see, take a look at the project on Github; it’s open source. I included a demo app with the library so definitely check it out or catch me on twitter if you have any questions.
The problem I was faced with was several fold. First, I needed to detect urls within a UITextView. When I clicked the links I wanted to be taken to a custom ‘in app Safari’ if you will. Inside the custom controller I also wanted to give the user the option of opening the link in Safari. This is a pretty common feature in most Twitter clients.
Believe it or not, this simple feature caused me the most headache out of anything I’ve ever done before regarding iPhone development. There is surprisingly little to no information on the Internet regarding this solution, so I’m thrilled to write a blog post about it and share it with everyone so none of you have to go through what I did.
Detecting links within a UITextView is the easy part.
textView = [[UITextView alloc] init];
textView.text = @"Visit http://www.google.com for great good.";
textView.dataDetectorTypes = UIDataDetectorTypeLink;
textView.editable = NO;
URLs are detected by setting the dataDectorTypes parameter to UIDataDetectorTypeLink, optionally set it to UIDataDetectorTypeAll to detect all data types. This will highlight the URL allowing the user to touch the link, which will open in Safari. The caveat is having to set editable = NO.
Creating the Custom UIWebView Controller
I owe a lot of my UIWebView code to the open sourced version of TwitterFon. I added a UIToolbar to the bottom to hold a back button, forward button, refresh button, and the action button. I made it as Tweetie-like as I could for granularity. When you invoke the action button a UIActionSheet will pop up asking the user if they want to open the page in Safari.
But how do we open our links in our custom UIWebView controller in the first place?
This part was hard to figure out, initially. I eventually found this post on stackoverflow. What they say to do is basically create a UIApplication category to override openURL. You would also need some sort of watcher to keep track of your current view controller. I threw something hacky together and found that it worked.
@implementation UIApplication (Private)
(BOOL)customOpenURL:(NSURL*)url
{
AppDelegate *watcher = [[UIApplication sharedApplication] delegate];
if (watcher.currentViewController) {
[watcher.currentViewController handleURL:url];
return YES;
}
return NO;
}
@end
This solution works, but it’s win/lose. You have the ability to open all links in your custom webview, but now it’s impossible to invoke UIApplication’s openURL which opens Safari since you are overriding the method.
One fix is actually to subclass UIApplication. Then, inside your category you can invoke [super openURL:url] if your watcher is nil, for instance. But subclassing UIApplication can be somewhat funky.
The solution I ended up with was much cooler anyway.
Method Swizzling
I had never heard of method swizzling before, but it sounded insane so I figured why not try it out. There’s plenty of resources on the Internet to hold your hand through this part. Basically, method swizzling is just a way to swap method implementations.
It’s very hacky and somewhat dangerous, so I don’t necessarily recommend it, but it works and does a swell job at it. Here’s what swizzling looks like in a nutshell.
#import <objc/runtime.h>
..
Method customOpenUrl = class_getInstanceMethod([UIApplication class], @selector(customOpenURL:));
Method openUrl = class_getInstanceMethod([UIApplication class], @selector(openURL:));
method_exchangeImplementations(customOpenUrl, openUrl);
With method swizzling, you swap implementations between separate methods. For this to be possible with OpenURL I still had to create a UIApplication (Private) category, but I named my new method customOpenURL:(NSURL*)url instead. Now I could swizzle between OpenURL and customOpenURL. All I had to do now was swizzle the implementations on initialization and when the user is in the custom UIWebView controller I unswizzle them to open in Safari. Great success.
I understand this might be confusing, especially if you’re new to Objective-C or iPhone development, but this is a really handy trick. I’m sure there’s plenty of things out there that you can apply this solution to. But my main focus was getting URL detection to open in a custom UIWebView or Safari, and I found that solution. I hope this helps!
The entire code is included in a demo app I put on Github so definitely check it out or catch me on twitter if you have any questions.
July 21st
If you haven’t heard about the Handy Light iPhone app trickery, then read this article: http://www.engadget.com/2010/07/20/handy-light-for-iphones-dirty-little-secret-tethering-video/
From the article:
You may ask yourself, why on earth would anyone pay 99 cents for an iPhone app whose sole purpose is to flash bright, solid colors? We certainly wouldn’t recommend it, but Handy Light has a great little Easter egg that undoubtedly doesn’t jive with the folks at Cupertino HQ. Like Nullriver’s Netshare app before it, this little piece of software allows for SOCKS proxy tethering, without having to sign up for AT&T’s tethering plan. Instructions available via the video below, and if you’re looking to pick up the app yourself, better hurry — we can’t imagine Apple will let this one stay in the store for very much longer.
Update: Looks like the app’s been pulled. Ye who snoozes, ergo must lose. If you did manage to nab and the video below isn’t working (we see it just fine), check out App Shopper for more detailed, text-based instructions.
That’s Handy Light in a nutshell. Disguised as a lame $0.99 cent colorful display app, Dade Murphy managed to sneak his way beyond the doors of the gibsons to bring us non-jailbreak tethering support through AT&T.
So what now, you might ask?
Well, with any good stunt, others are sure to follow. So myself along with my friend Mac pushed out a replica app dubbed “Handy Flashlight” which gives you the exact same experience in case you missed the app after it got pulled. Sorry—no tethering support in this one! ;)

The app took hardly no time at all. It was cranked out in a single night and submitted for approval all in one sitting. We’ll see how long it takes Apple to get it approved. Hopefully quick enough for the hype to stick around!
Don’t forget the “secret code”: Blue, Yellow, Red, Upper Right Corner Screen!
UPDATE:
This app went into review on Monday, July 26th at 4:06 PM and it’s still currently sitting there as of Tuesday July 27th at 7:07 PM. That’s way longer than normal, especially for testing if the screen changes color. I’m almost certain Apple is paranoid that I hid secret tethering features inside the app. I’m also certain that I’m wasting countless hours of their time. :)
UPDATE 2:
Looks like Apple approved the app! Only 3 days later, July 29th at 10:30pm. :)
http://itunes.apple.com/us/app/handy-flashlight/id383845539?mt=8
I was bored on the night of July 1st. I decided it was time to brainstorm my next app for the upcoming weekend. Earlier in the week, I went to Sutro Baths around 2am with a few friends and without a flashlight. Luckily, I opened up my new iPhone 4’s camera app and set the flash to on. Instant flashlight. Now all I had to do was replicate this in a one-click process to give myself a flashlight. Simple enough.
After work that Friday on the 2nd, I slapped something together to show off to my coworkers. I had a working flashlight app. At that time, all the app did was display a black screen and turn the flash on when you opened the app. I wasn’t convinced this was $0.99 worthy…I’m still not. :)
The app now has the ability to double-tap the flash on or off, and you can swipe the touch screen to make the view turn white or black.

This is about as simple as it gets, but it’s still $0.99 for now. And please, don’t buy this app. DM me for a promo code @marksands
Download it here http://itunes.apple.com/us/app/camlight/id383027043?mt=8
2 Promo Codes while they last:
NJKL7MER66N4
4AY9LM79NW9J