This is a mini guide on how you can build a iOS wrapper to run your web app.

This is an excerpt from my upcoming Clear Hybrid Apps ebook. Visit the site, subscribe to the newsletter and I’ll let you know when it’s ready or when another post this is published here.

Why not use Phonegap, you ask? Yes, it is a great tool but perhaps you you want something simpler or learn how to do it from scratch.

First you need to install Xcode from the App store on your Mac. You really need a Mac or a VM with Mac OS X.

If you don’t know how to program in Objective C don’t worry, you will learn a little as you follow this guide.

Open Xcode and start a new project. Choose the “Empty Application” template.

Enter the project name, your information and the device type. For this example I picked just an iPhone app. Next, choose a location where to save the project and click “Create”.

We’re now presented with the default view for the project. You can see the file tree on the left, the utilities on the right column and the file being edited in the main centre area. Don’t worry you don’t yet understand everything in this window, you will learn bit by bit.

Let’s see what the app is up to. Click on the play button on the top left (or just press CMD-R).

The project builds and after a couple of seconds the iOS Simulator opens and you’re presented with your app. As we picked earlier the empty app template, there is not much to see, just a empty screen, but it is our app empty screen.

Let’s create something to put in there. First, quit the app on the Simulator (press the Stop button in the Xcode window). On the left column click on the “AppDelegate.m” file. This should open the file in the main editor.

There is a lot of boilerplate stuff here. This file is the main entry point to an iOS app and we’re going to create here a controller to manage the navigation for us, like any other iOS app.

Locate the application:didFinishLaunchingWithOptions: method. Should be on a line like this:

This method is called by iOS when the application finishes launching (hence the name), and as you can see the default action is to create a single window of the same size as the screen and set its backgound colour to white.

Place your cursor on the comment that says “Override point…”, and paste this block. You can enter some new lines to make it clearer.

Call the file WebViewController and make it a subclass of a UIViewController. We will be doing everything in code, so don’t pick the checkbox to create the XIB as well. Click on Next, add it to the project by clicking on the Create button. You can costumize a lot of the project but the defaults are usually good enough.

There will be two new files in the project WebViewController.h and WebViewController.m with some boilerplate in there. You can remove some of it later, but let’s leave everything as it is for now.

First thing, let’s integrate this into the AppDelegate code we did earlier. Open the AppDelegate.m file again and on the top of the file include the WebViewController.h file. Type the following on a new line after the other include that is in there

Objective-C

1

2

#import "AppDelegate.h"

#import "WebViewController.h"

This will include the WebViewController declaration in this file so it can be found. On the application:didFinishLaunchingWithOptions method, before the (…) initWithRootViewController:nil (…) file, type the following line:

Objective-C

1

WebViewController*wbc=[WebViewControllernew];

and replace “nil” with the “wbc” variable in the next line, so you end up with this:

(you can see I hid the right column and the debug console to maximise the editor area, you can toggle them with the buttons on the top right of the Xcode window).

You can run the app again. It should compile and launch without any issues but you won’t see anything different.

We’re going to need add two things to the WebViewController public declaration: a string to set the address the view should load, and the web view itself. Open the WebViewController.h file and type the following between the @interface and @end lines.

Objective-C

1

2

@property(nonatomic,strong)UIWebView*webView;

@property(nonatomic,strong)NSString*address;

This declares the two properties. Xcode handles the details for us.

Open the corresponding .m file and inside the initWithNibName:bundle method, on the same spot as the comment that says “Custom initialization”, enter the following:

Objective-C

1

2

3

self.webView=[UIWebViewnew];

self.webView.frame=self.view.frame;

[self.view addSubview:self.webView];

Run the app again, and while it doesn’t seem too different, you can now drag the screen up and down, as you’re now acting on the web view. It is empty because we haven’t yet told it what to load.

To specify what address to load we’re going to set corresponding property when we initialise the WebViewController object in the app delegate. Open the file and type the following:

Objective-C

1

wbc.address=@"https://bbc.co.uk";

We need to instruct the webview to load this address when the view is loaded. Open WebViewController.m and after the viewDidLoad method, after the comment, add this new method:

Objective-C

1

2

3

4

5

6

7

8

-(void)viewWillAppear:(BOOL)animated

{

[super viewWillAppear:animated];

NSURL*url=[NSURL URLWithString:self.address];

NSURLRequest*request=[NSURLRequest requestWithURL:url];

[self.webView loadRequest:request];

}

Press Run and the BBC homepage should load in your app!

There is still a lot to do. There is not way to go back, the pages load in the same web view, there is no loading indicator and the navigation bar title is empty.

The webview generates some events we can tap into. First, we need to change the declaration of the WebViewController to tell the compiler it understands these events. Open WebViewController.h and change the @interface line to:

Objective-C

1

@interfaceWebViewController: UIViewController<UIWebViewDelegate>

To use native navigation we’re going to tap into an event webView:shouldStartLoadWithRequest:navigationType: (what a mouthful). You need to implement this method in your view controller and return YES or NO depending on whether you want this request to continue. To use native navigation we’re going to do a little trick: we will trap the request and cancel it but as we get the destination address, we’ll use it to configure and push a new view controller to the stack.

When the webview is created, set its delegate to the containing view controller.

You can now see the browsing activity follows the regular iOS conventions and you can go back pressing the button or swiping from the left edge.

To set the view title to the document title, implement the webViewDidFinishLoad: delegate method that is called when the loading finishes. After that, it is just a matter of getting the document.title using a little Javascript.

To implement a loading indicator, we can use the standard loading status bar indicator. On loading start we set the indicator to visible and hide it when loading stops.

As you can see it is now visible when there is some loading activity.

And this concludes this simple guide how on to do native container for your web app, a mini clone of Phonegap. It shows that with some care you can avoid using resource-heavy frameworks and that doing a little native code doesn’t byte you

The BBC web site is a little heavy and slow to load, but this is only an example. A custom web app should be much faster.

The chargers are rated from 1 to 5 energy bolts, with 5 bolts the best. The overall rating below is the average of the ratings in nine different categories, based on my measurements of efficiency, power stability, power quality, and power output. The quick summary is that phone manufacturers provide pretty good chargers, the aftermarket chargers are worse, and $2 counterfeit chargers are pretty much junk. Much to my surprise, the HP TouchPad charger (which isn’t sold any more) turned out to have the best overall score. The counterfeit iPhone charger set a new low for bad quality, strikingly worse than the other two counterfeits.

“[…] I casually advise a few young companies, and I’m always surprised when I see them overthinking simple problems, adding too much structure too early, and trying to get formal too soon. Start-ups should embrace their scrappiness, not rush to toss it aside. The ability to run with scissors is a blessing, not a curse.”