TwitterCounter for @bigclick_dean

dBlog.com.au

My Development Blog

Posts Tagged ‘ iphone sdk ’

In this installment we will be creating the “framework” for our application, first up we will be creating our UITabBarController and then we will add some ViewControllers to represent our different views.

1. Create a “Window-Based” application template

I had originally intended to create the application based on a “Navigation-Based” application template but now I have decided to create everything from scratch and not use Interface Builder. So if you have already completed part 2 then I suggest you go back there and follow the instructions to create the new “Window-Based” application template.

2. Setting up the UITabBarController and its delegate

Open up RSSReaderAppDelegate.h and edit the code to look like below


#import <UIKit/UIKit.h>

@interface RSSReaderAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) UITabBarController *tabBarController;

@end

What we have done here is added the UITabBarControllerDelegate and created a UITabBarController instance called tabBarController.

Now you will need to open up RSSReaderAppDelegate.m and synthesize the tabBarController instance and alter the applicationDidFinishLaunching function to look like this


- (void)applicationDidFinishLaunching:(UIApplication *)application {

tabBarController = [[UITabBarController alloc] initWithNibName:nil bundle:nil];

// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];

// Override point for customization after application launch
[window makeKeyAndVisible];
}

This will allocate and init the UITabBarController and then add it to the window (we haven’t added any buttons yet, but we will do this shortly).

If you run your application now you should see the UITabBar at the bottom of the window like so:
UITabBar with no buttons

3. Creating our UINavigationController

Right Click on the Classes folder in the left hand column and click Add > New File… , the following window will appear
XCode: Add new File

Now choose UIViewController subclass and click next, now name the class MainViewController.m and click Finish.

You should now have a MainViewController.h and a MainViewController.m file in your Classes folder. Open up MainViewController.h and edit its contents to below:


#import <UIKit/UIKit.h>

@interface MainViewController : UINavigationController {
UINavigationController *navigationController;
}

@property (nonatomic, retain) UINavigationController *navigationController;

@end

Notice we have changed the subclass from UIViewController to UINavigationController and we have added a UINavigationController instance.

Now open up MainViewController.m and edit its contents to below:


#import "MainViewController.h"

@implementation MainViewController

@synthesize navigationController;

- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"Main View Did Load: %@", self.tabBarItem.title);
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}

- (void)dealloc {
[super dealloc];
}

@end

All we have done here is synthesized the navigationController instance and put a NSLog call to display when the controller is created and what its TabBar item title was when it was created.

If you run the application now you wont see anything different, this is because we haven't added anything to the UITabBarController yet. To add the buttons you will need to open up the RSSReaderAppDelegate.m file and edit the applicationDidFinishLaunching function to look like below:


- (void)applicationDidFinishLaunching:(UIApplication *)application {

tabBarController = [[UITabBarController alloc] initWithNibName:nil bundle:nil];

// Create instances of the MainViewController for the 4 TabBar buttons
MainViewController *viewController1 = [[[MainViewController alloc] initWithNibName:nil bundle:nil] autorelease];
viewController1.tabBarItem.title = @"Browse All";
MainViewController *viewController2 = [[[MainViewController alloc] initWithNibName:nil bundle:nil] autorelease];
viewController2.tabBarItem.title = @"Most Recent";
MainViewController *viewController3 = [[[MainViewController alloc] initWithNibName:nil bundle:nil] autorelease];
viewController3.tabBarItem.title = @"Favourites";
MainViewController *viewController4 = [[[MainViewController alloc] initWithNibName:nil bundle:nil] autorelease];
viewController4.tabBarItem.title = @"Settings";
tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, viewController3, viewController4, nil];

// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];

// Override point for customization after application launch
[window makeKeyAndVisible];
}

What we are doing here is creating 4 instances of the MainViewController and setting the tabBarItem title (this displays below TabBar icon). Once we have created all four of the View Controllers we add them to the tabBarController by setting its viewControllers property to an array containing the pointers for our 4 View Controllers. Remember that you need to have a nil value at the end of the array to indicate the last element.

If you run your application now you should see 4 TabBar items with the titles we have assigned them above. You will also notice that we have a Navigation bar at the top of our window, as we don't have a UITableView setup yet the Navigation bar will just be blank.

iPhone SDK: RSS Reader - TabBar & NavigationController working

4. Setting up our UITableViews

Now for starters we are going to need 4 UITableViewControllers for our Browse, Recent, Favourites and Settings Tabs. We will start with the stock standard ones and customize them as we go along.

Right Click the Classes folder in the left hand column and click Add > New File...
Select UITableViewController subclass and click Next
Call the first one BrowseViewController.m and then click Finish
Repeat these steps and create a RecentViewController, FavouritesViewController and SettingsViewController

Now that we have all our stock standard UITableViewControllers created we have to connect them up, we will be doing this in the MainViewController.m file, so open it up and edit its viewDidLoad function to below:


- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"Main View Did Load: %@", self.tabBarItem.title);
if(self.tabBarItem.title == @"Browse All") {
BrowseViewController *browseViewController = [[BrowseViewController alloc] init];
[self pushViewController:browseViewController animated:YES];
[browseViewController release];
} else if (self.tabBarItem.title == @"Most Recent") {
RecentViewController *recentViewController = [[RecentViewController alloc] init];
[self pushViewController:recentViewController animated:YES];
[recentViewController release];
} else if (self.tabBarItem.title == @"Favourites") {
FavouritesViewController *favouritesViewController = [[FavouritesViewController alloc] init];
[self pushViewController:favouritesViewController animated:YES];
[favouritesViewController release];
} else if (self.tabBarItem.title == @"Settings") {
SettingsViewController *settingsViewController = [[SettingsViewController alloc] init];
[self pushViewController:settingsViewController animated:YES];
[settingsViewController release];
}

}

Now this may not be the most traditional method and isn't very good for massive applications that use heaps of view controllers, etc but it worked fine for my needs and meant I only needed one UINavigationController (MainViewController). What it does is it checks the title of the TabBar item that it is linked to, it then decides which UITableViewController to push into view.

Also don't forget to #import the four new header files


#import "BrowseViewController.h"
#import "RecentViewController.h"
#import "FavouritesViewController.h"
#import "SettingsViewController.h"

If you run your application now you will wee that we have a UITableView visible on each of the TabBar items, but we currently cant tell which one is which as they all look the same.

5. Identifying and Customising our UITableViews

Starting with our BrowseViewController we want to open up the BrowseViewController.m file and alter it's viewDidLoad function to below:


- (void)viewDidLoad {
[super viewDidLoad];

self.title = @"Browse All";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:nil];
}

We have set the title to "Browse All" and we have added a button to the right hand side of the navigation bar, this button is an add button (as indicated by UIBarButtonSystemItemAdd) and currently its action is set to nil, in the future we will connect this up to an UIActionSheet.

Now go through the other three controllers (RecentViewController, FavouritesViewController and SettingsController) and just set the title, not the rightBarButtonItem!

If you run your application now you should be able to navigate through it and see the title change and on the Browse All tab you should see an add button at the top right, although it wont do anything when you press it.

Browse All TabMost Recent TabFavourites TabSettings Tab

6. Download the Project Files

Click Here to download my version of the Project files, you can use these to work your way through any problems or even to work backwards to see how I do things.

7. Whats Next?

In the next installment we will be creating our SQLite database and adding some feeds and groups, we will also be setting up the BrowseViewController to handle multiple levels of groups with only one view (Drilldown) and we will also be looking at storing images in a SQLite database with a BLOB field.

PLEASE CLICK HERE TO RE-TWEET THIS TUTORIAL

Please do anything you can to spread these tutorials around as the more people that read the faster I will write tutorials!

Popularity: 15% [?]

This installment will walk you through creating a new Xcode project and getting everything ready to start the coding. The iPhone SDK comes ready to dive in but we need to confiure our SQLite and TouchXML libraries and get our workspace up to scratch!

1. Creating a new Xcode project

Start Xcode by clicking the icon in your dock or by running “Xcode” in your /Developer/Applications folder.

Click File > New Project and the following window will appear

Xcode New Project Window

For our RSS Reader application we are going to be using the “Window-Based Application” template, this can be found under the “iPhone OS” group in the left hand column. Simply double click the “Window-Based Application” in the Right hand column and give your project a name (I will be calling the project RSSReader).

Once you have created the project the main Xcode window will appear

Default Xcode window

2. Laying out your screen

I personally don’t like the default layout for Xcode and it can get quite hectic when you are trying to debug, code and watch the build logs at the same time. So what can you do? Thankfully Apple has provided an “All-in-one” layout and here is how you can activate it.

First you need to close your newly created project, don’t worry as it will all be saved already.
Now go to Xcode > Preferences and the following window will appear

Xcode preferences window

The General tab should be selected, if not then click on it.
You will see the “Layout” drop-down with “Default” selected, click this and choose “All-in-one” and click OK to close the window.

Now go to File > Open Recent Project and select RSSReader.xcodeproj (or whatever you called your project) from the list.

You may not notice a huge difference but there should be some icons at the top left corner of the window that will allow you to switch between the different pages (Project and Debug) and you will also now have “Project Find”, “SCM Results” and “Build” tabs in the Project page. Below is how mine looks and you will notice that I have expanded the “RSSReader” group in the left hand column.

Xcode All-in-one Window

Now that we have the All-in-one layout activated we can adjust a few things to make it a “perfect” working environment.

If you expand the “Classes” folder in the left hand column you will see a series of files (header and main files for our AppDelegate), click one of there and the right hand column should look like this.

Code Editor View

You need to drag the horizontal seperator between the two panels on the right hand side all the way to the top to give you the most code-view area possible, once you have done that it should look like this.

Resized Code Editor View

3. Add the SQLite framework to our project

By default the SQLite framework isn’t included in the project template and you will need to add it manually.

To do this you will need to right click on the Frameworks folder in the left hand pane, then click on Add > Existing Frameworks… Now navigate to /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk/usr/lib/ and double click the “libsqlite3.0.dylib” file. This folder may change depending on the version of your iPhone SDK, the only bit that should change is the “iPhoneOS2.0.sdk” bit, this wont be a problem as it is still the same version of the framework across all the SDK releases.

The following pop-up will appear, simply click Add and the library will be added to your project.

Add Framwork Dialog

4. Add the TouchXML libraries to our project

As we will be using TouchXML for our xml parsing, we will need to import the required files we downloaded in Part 1 and also edit some of the project settings.

Go to Project > Edit Project Settings and a new window will appear with 4 tabs at the top (General, Build, Configurations and Comments). We are only interested in the Build tab at the moment, so go ahead and click the Build Tab and the following window will appear.

Project Settings Window

Make sure that you change the Configuration dropdown to “All Configurations” otherwise you may have trouble when testing on a device later on.

The settings that we are interested in are “Header Search Paths” and “Other Linker Flags”, you can easily find these by typing the beginning of the name into the Quick Find at the top right of the window.

You need to add “/usr/include/libxml2″ to the “Header Search Paths” and you need to add “-lxml2″ to the “Other Linker Flags”.

Once you have done this you can close the settings window and you will be back at your project window.

Now that the libxml2 libraries have been included you will need to import the TouchXML files to your project, to keep everything neat and tidy we will create a new “Group” to organise the files.

Right click on the “Classes” folder in the left hand column and click Add > New Group and call it TouchXML

Now its time to import the TouchXML files, simply right click on the new “TouchXML” folder in the left hand pane and click Add > Existing Files…

You will be presented with a finder window and you will need to navigate to the location that you downloaded the TouchXML files out to (in my case it was /Developer/ExtraLibraries/) and then keep going to the following path “touchcode-read-only/TouchXML/Common/Source/” and select all the files and click Add.

You should now see the CXML* files in your left hand pane and they are now available to your project.

5. And then?

We are now all setup and ready to start building the application, the next post will go over exactly what we will be building and the general structure of the application and how it will work. Remember to have a read through my other tutorial so you will have a bit of a headstart on the way to use the different technologies.

Remember to grab me on Twitter at @bigclick_dean for regular updates!

Popularity: 6% [?]

This tutorial series will walk you through the creation of a complete, ready to publish iPhone application. I have chosen to continue the Advanced RSS Reader application but I will be taking a step back and extending on some of the methods explained in those tutorials.

When this series is completed you will have learnt (hopefully!) how to setup a new iPhone application, use UITableViews & UINavigationControllers, interact with SQLite databases, read RSS/XML feeds by using TouchXML, test your project on actual iPhone hardware, prepare your application for submission to the App Store and much more.

1. Tools you are going to need

iPhone SDK -Apple has created a superb set of tools that are going to become your best friends while you work your way through this tutorial series and iPhone development in general.
TouchXML Libraries – As many of you may know the NSXMLDocument implementation was removed from the iPhone SDK due to its hefty processing requirements, so thats why we use TouchXML to provide the basic XML parsing options that we need.
SQLite Manager Plugin for FireFox – As we are going to be working with SQLite databases we need to be able to create our database structure and to browse through it easily. You can use the command line or any application that supports SQLite databases, although I have grown very fond of the SQLite Manager Plugin for Firefox (available at http://addons.mozilla.org/en-US/firefox/addon/5817)


2. Downloading & Installing the iPhone SDK

You can grab the iPhone SDK from the iPhone Dev Centre (http://developer.apple.com/iphone/), you will need to create an account to get access to the download, but don’t worry…it’s FREE!

Once the download has finished (its a heavy 1Gb+ download so now’s the best time to take a nap) you can simply run the package and go through the standard install process. By default it will install the developer tools into /Developer/ and there will no icons in your applications folder or your dock.

Under the /Developer/Applications folder you will see a bunch of applications and folder, the two we are going to be concentrating on are “Xcode” and “Interface Builder”.

picture-15picture-16

I suggest that you drag these to your dock for easy access as we are going to be using them alot! I will come back to these applications in the next tutorial as we need to install some more tools first.

3. Downloading and Setting up the TouchXML Libraries

You will need to check the latest code out from the TouchXML SVN Repository, if you don’t know how to use SVN I have included the required commands below.

1. Launch a new Terminal window
2. Create a new folder called “ExtraLibraries” where you would like to keep your iPhone development libraries (I save mine in /Developer/ExtraLibraries/ to keep evenything clean and reusable)

mkdir /Developer/ExtraLibraries

3. Change into the new folder

cd /Developer/ExtraLibraries

4. Run the SVN checkout code

svn checkout http://touchcode.googlecode.com/svn/trunk/ touchcode-read-only

You will see the filenames scrolling up the screen and depending on your connection it should only take around 60 seconds to grab all the required files. If you have a look in the newly created folder you will see the TouchXML folder along with some other libraries (TouchSQL, TouchJSON, TouchHTTPD, etc). We wont be using these other libraries but feel free to have a play around with them and see what you can do.

5. Now you have the TouchXML libraries on your local machine ready to start creating your first iPhone app.

4. Installing the SQLite Manager Plugin for FireFox

I like to use the visual editor in FireFox but by no means is it the only option, I will provide a database download for those that have trouble getting their own one built.

To install the FireFox plugin simply open up FireFox and visit http://addons.mozilla.org/en-US/firefox/addon/5817 and click “Add to FireFox”, you will need to go through the usual process of installing an add-on and after that it will be available at Tools > SQLite Manager, if you launch the manager the following window should appear:

picture-17

5. Are you ready?

Well that’s all the essential tools installed and ready to go! Go and have a play and a look at the applications and get ready for the next installment for the series.

I hear you asking “What is the next installment going to outline and when will it be out?”…The next installment is going to go through setting up a new project, organising our development windows and getting the TouchXML and SQLite libraries set up for our project. I am hoping to have the next installment out in a few hours and then it will be time to get into the “meat” of the project!

Now it’s time for a shameless plug…If you need any Web Design or Development in Australia or for that matter the world, then please check out Big Click Studios. Big Click is a Sydney Web Design Agency that I run and we do AMAZING work (I may be biased ;-) , click here to check out our portfolio.

Popularity: 8% [?]

Well I have been asked this a few times and I can see how it would be a very helpful addition to the UIWebView’s feature set. What I am talking about is adding the ability to intercept the event generated when a user selects a link in a webpage being displayed with a UIWebView, this will then allow you to perform any action that you want.

When would you use this I hear you say? Well one person asked me if I knew how to append the users current location onto all HTTP requests? and another just wanted to know how to perform custom actions from an embedded UIWebView.

Once again I will be extending the “Build your very own Web Browser!”, if you haven’t already completed it then I suggest that you head over there now and spend 5 minutes reading it and then downloading the project files at the end.

Start by opening up the WebBrowserTutorialAppDelegate.h file and editing the @interface line to read:

@interface WebBrowserTutorialAppDelegate : NSObject <UIWebViewDelegate> {

What we have done is to make the main AppDelegate a delegate for the UIWebView as well.

Now we need to set our webView to have the main AppDelegate as its delegate, you can do this by opening up WebBrowserTutorialAppDelegate.m and putting the following line just inside the applicationDidFinishLaunching function:

webView.delegate = self;

That is all pretty self explanatory, it just sets the delegate of our webView to self, which in this case is our main application delegate.

Now we are pretty much done, we just need to add the function to catch the link clicks. To do this we need to add a new function, copy the content below to the WebBrowserTutorialAppDelegate.m file:

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
	NSURL *url = request.URL;
	NSString *urlString = url.absoluteString;
	NSLog(urlString);
	return YES;
}

This function will catch all requests and allow you to either manipulate them and pass them on or to perform your own custom action and stop the event from bubbling.

The first line gets the URL of the request, this is the contents inside the href attribute in the anchor tag.
The next line converts the URL to a string so we can log it out. You can access many parts of the NSURL, here are some of them and brief description of what they do.

* absoluteString – An absolute string for the URL. Creating by resolving the receiver’s string against its base.
* absoluteURL – An absolute URL that refers to the same resource as the receiver. If the receiver is already absolute, returns self.
* baseURL – The base URL of the receiver. If the receiver is an absolute URL, returns nil.
* host – The host of the URL.
* parameterString – The parameter string of the URL.
* password – The password of the URL (i.e. http://user:pass@www.test.com would return pass)
* path – Returns the path of a URL.
* port – The port number of the URL.
* query – The query string of the URL.
* relativePath – The relative path of the URL without resolving against the base URL. If the receiver is an absolute URL, this method returns the same value as path.
* relativeString – string representation of the relative portion of the URL. If the receiver is an absolute URL this method returns the same value as absoluteString.
* scheme – The resource specifier of the URL (i.e. http, https, file, ftp, etc).
* user – The user portion of the URL.

Then the third line simply logs the URL to the console, so you will new to open up the console while you run this in the simulator to see the results.

Finally the forth line returns YES, this will allow the UIWebView to follow the link, if you would just like to catch a link and stop the UIWebView from following it then simply return NO.

I hope this will help someone to make a browser with some nice user interaction features.

Thanks,
-Dean

Popularity: 14% [?]

Well I needed a way to get a formatted date string in NSString format so I dug around and came up with the following function.

-(NSString *) dateInFormat:(NSString*) stringFormat {
	char buffer[80];
	const char *format = [stringFormat UTF8String];
	time_t rawtime;
	struct tm * timeinfo;
	time(&rawtime);
	timeinfo = localtime(&rawtime);
	strftime(buffer, 80, format, timeinfo);
	return [NSString  stringWithCString:buffer encoding:NSUTF8StringEncoding];
}

What it does it it takes a NSString as input with set specifications (checkout http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/strftime.3.html for the full list of specifications) and it returns the compiled date string as a NSString ready for you to use.

It is pretty much just a wrapper for the C strftime function but I thought it would be helpful to share as you often need dates or times in games/applications.

Here are some usage examples and their expected outputs:

[self dateInFormat:@"%s"] // Should return a UNIX timestamp, i.e. "1222738875"

[self dateInFormat:@"Today is %A"] // Should return "Today is Tuesday"

[self dateInFormat:@"%+"] // Should return "Tue Sep 30 11:50:01 EST 2008"

[self dateInFormat:@"%Z (%z)"] // Should return timezone + UTC offset in brackets, i.e. "EST (+1000)"

[self dateInFormat:@"%Y-%m-%d-%H:%M:%S"] // Should return a date/time stamp as used my many programs (MySQL, PHP, etc) i.e. 2008-09-30-11:54:03
NOTE: You can also use [self dateInFormat:@"%Y-%m-%d-%X"] to get the same result as above.

I hope that this function will be able to same someone 5-10 minutes as I know I will be using it for a few of my projects.

Popularity: 2% [?]

I thought i would make this a separate post to the Build your very own Web Browser! tutorial as it can be used for many different purposes and it took me a bit to figure it out.

For my example I am going to be trying to use a file in my local bundle in a UIWebView, my file is going to be called “sample.jpg” and it will be in the root folder of my project, this will work for any folder though.

I will show you the code and then I will explain it.

NSString *imagePath = [[NSBundle mainBundle] resourcePath];
imagePath = [imagePath stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
imagePath = [imagePath stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

NSString *HTMLData = @"
<h1>Hello this is a test</h1>
<img src="sample.jpg" alt="" width="100" height="100" />";
[webView loadHTMLString:HTMLData baseURL:[NSURL URLWithString: [NSString stringWithFormat:@"file:/%@//",imagePath]]];

Line 1
This will get the path to the main bundle root folder.

Line 2
We need the slashes to be double slashed to work correctly in the UIWebView, so we are searching for all instances of “/” and replacing it with “//”

Line 3
Same deal as above but we are searching for a space and replacing it with the HTML equivalent of %20

Line 4
This is putting some sample data together for out UIWebView, you will see that we have set the images source to just our “sample.jpg” file as it is sitting in the root folder, if it was in a folder called “images” we would need to set the source to “images//sample.jpg”. Remember the double slashing!

Line 5
This is pretty much the same as my example in the tutorial although we are setting the baseURL to the root of our application bundle, this allows us to reference everything relatively instead of absolute paths.

Well thats about it, if you have done my Build your very own Web Browser! tutorial you will be able to replace the contents of applicationDidFinishLaunching with the above code (don’t forget to leave the makeKeyAndVisible line in there) and you will be loading content from your local device in no time!

Popularity: 10% [?]

I see many people asking for SQLite tutorials around, and since I am using SQLite for the next part in the Advanced RSS Reader Tutorial, I thought I would write up a quick tutorial on using SQLite with the iPhone SDK.

1. Project Requirements

I suggest that you have at least a basic understanding of SQLite, writing SQL statements, the XCode interface and using the terminal in OSX. If you don’t know anything about any of these topics then this tutorial probably isn’t for you.

2. Creating our SQLite database for our tutorial

We first need to create a database for use with our application. For the purposes of this tutorial we will be building a database of animals along with a little information on them and a picture.

Fire up a new Terminal window and make a new folder to store the database in, here are the commands I ran

cd /Users/lookaflyingdonkey/Documents
mkdir SQLiteTutorial
cd SQLiteTutorial
sqlite3 AnimalDatabase.sql

You should now be at a “sqlite” command prompt, this is where we will be building our database structure and entering some test data.

For our example we need the name of the animal, a short description and a link to an image. Follow the commands below to create the table and to enter some sample data.

CREATE TABLE animals ( id INTEGER PRIMARY KEY, name VARCHAR(50), description TEXT, image VARCHAR(255) );

INSERT INTO animals (name, description, image) VALUES ('Elephant', 'The elephant is a very large animal that lives in Africa and Asia', 'http://dblog.com.au/wp-content/elephant.jpg');
INSERT INTO animals (name, description, image) VALUES ('Monkey', 'Monkies can be VERY naughty and often steal clothing from unsuspecting tourists', 'http://dblog.com.au/wp-content/monkey.jpg');
INSERT INTO animals (name, description, image) VALUES ('Galah', 'Galahs are a wonderful bird and they make a great pet (I should know, I have one)', 'http://dblog.com.au/wp-content/galah.jpg');
INSERT INTO animals (name, description, image) VALUES ('Kangaroo', 'Well I had to add the Kangaroo as they are the essence of the Australian image', 'http://dblog.com.au/wp-content/kangaroo.jpg');

The first command will create the table with the required structure and the next four will insert some test data for us to work with. To ensure that you have entered the data correctly you can execute “SELECT * FROM animals;” and see if it returns the items above. Once you are confident that everything had been created successfully you can leave the sqlite command line by typing “.quit”.

3. Creating our Project

Now that our database is all ready to go we need to setup our X-Code project.

Start off by creating a new “Navigation-Based Application”.

Give your Project a name, I called mine “SQLiteTutorial”.

Now set your screen layout to how you prefer it, I suggest making the window as large as possible, and making the code view as tall as possible by dragging the horizontal slider to the top. This will allow you the most room to move when building your application.

Now its time to create the required classes and views for our application, we will start off by making our views.

Right Click on the “Resources” folder in the left hand pane and click “Add File”, we want to create a new “View XIB” under the “User Interfaces” group.

We now need to give it a name, to stick the Apple’s naming conventions we are going to call it “AnimalViewController.xib”, Now Click “Finish”.

Now we need to create two classes, the first one will represent an animal, right click on the “Classes” folder in the left hand pane, click “Add > New File…”, choose the “NSObject subclass” template under the “Cocoa Touch Classes” group and name it “Animal”.

The second class will be for our AnimalsViewController, right click on the “Classes” folder in the left hand pane, click “Add > New File…”, choose the “UIViewController subclass” under the “Cocoa Touch Classes” group and name it “AnimalViewController”.

4. Adding SQLite Framework and our Animal Database

Now that we have created all of our views and classes it is time to start the real grunt work.

First off we need to include the SQLite libraries so our application can utilise them. To do this you will need to right click on the “Frameworks” folder in the left hand pane, then click on “Add > Existing Frameworks…”, then navigate to “/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk/usr/lib/” and double click the “libsqlite3.0.dylib” file. A popup will appear, just click “Add” and the library will be added to your project.

We also need to add our database we created earlier to the Resources folder, to do this simply right click on the “Resources” folder, click “Add > Existing Files…”, navigate to the location you created the database in then double click on the AnimalDatabase.sql file. Another popup will appear, just click add.

All done with the importing, time to code!

5. The Coding begins!

We are going to start the coding by building our “Animal” object, every animal will have 3 properties, a name, a description and an image URL.

Open up the “Animal.h” file from the “Classes” folder and edit its contents to look like below,

#import <UIKit/UIKit.h>

@interface Animal : NSObject {
	NSString *name;
	NSString *description;
	NSString *imageURL;
}

@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *description;
@property (nonatomic, retain) NSString *imageURL;

-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u;

@end

Most of the above code should be pretty familiar to you, the only thing that may not be is the initWithName line, this line will allow us to create a new object with the required data, we could have used the default init function, but it will be easier for us to define our own.

Now we will actually have to implement the Animal Object, open up the “Animal.m” file and edit its contents to look like below:

#import "Animal.h"

@implementation Animal
@synthesize name, description, imageURL;

-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u {
	self.name = n;
	self.description = d;
	self.imageURL = u;
	return self;
}
@end

The above code should be pretty easy to read as well, it basically stores the supplied data from the initWithName function and return the object (self).

Now its time to setup the Application delegate to access the database.

Open up the “SQLiteTutorialAppDelegate.h” and edit its contents to look like below:

#import <UIKit/UIKit.h>
#import <sqlite3.h> // Import the SQLite database framework

@interface SQLiteTutorialAppDelegate : NSObject  {

    UIWindow *window;
    UINavigationController *navigationController;

	// Database variables
	NSString *databaseName;
	NSString *databasePath;

	// Array to store the animal objects
	NSMutableArray *animals;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) NSMutableArray *animals;

@end

What we are doing here is importing the SQLite database framework and creating some variables for storing the database details and an array of animal objects.

Now open up the “SQLiteTutorialAppDelegate.m” file and edit its contents to look like below:

#import "SQLiteTutorialAppDelegate.h"
#import "RootViewController.h"
#import "Animal.h" // Import the animal object header

@implementation SQLiteTutorialAppDelegate

@synthesize window;
@synthesize navigationController;
@synthesize animals; // Synthesize the aminals array

- (void)applicationDidFinishLaunching:(UIApplication *)application {
	// Setup some globals
	databaseName = @"AnimalDatabase.sql";

	// Get the path to the documents directory and append the databaseName
	NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *documentsDir = [documentPaths objectAtIndex:0];
	databasePath = [documentsDir stringByAppendingPathComponent:databaseName];

	// Execute the "checkAndCreateDatabase" function
	[self checkAndCreateDatabase];

	// Query the database for all animal records and construct the "animals" array
	[self readAnimalsFromDatabase];

	// Configure and show the window
	[window addSubview:[navigationController view]];
	[window makeKeyAndVisible];
}

- (void)applicationWillTerminate:(UIApplication *)application {
	// Save data if appropriate
}

- (void)dealloc {
	[animals release];
	[navigationController release];
	[window release];
	[super dealloc];
}

-(void) checkAndCreateDatabase{
	// Check if the SQL database has already been saved to the users phone, if not then copy it over
	BOOL success;

	// Create a FileManager object, we will use this to check the status
	// of the database and to copy it over if required
	NSFileManager *fileManager = [NSFileManager defaultManager];

	// Check if the database has already been created in the users filesystem
	success = [fileManager fileExistsAtPath:databasePath];

	// If the database already exists then return without doing anything
	if(success) return;

	// If not then proceed to copy the database from the application to the users filesystem

	// Get the path to the database in the application package
	NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];

	// Copy the database from the package to the users filesystem
	[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];

	[fileManager release];
}

-(void) readAnimalsFromDatabase {
	// Setup the database object
	sqlite3 *database;

	// Init the animals Array
	animals = [[NSMutableArray alloc] init];

	// Open the database from the users filessytem
	if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
		// Setup the SQL Statement and compile it for faster access
		const char *sqlStatement = "select * from animals";
		sqlite3_stmt *compiledStatement;
		if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
			// Loop through the results and add them to the feeds array
			while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
				// Read the data from the result row
				NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
				NSString *aDescription = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
				NSString *aImageUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];

				// Create a new animal object with the data from the database
				Animal *animal = [[Animal alloc] initWithName:aName description:aDescription url:aImageUrl];

				// Add the animal object to the animals Array
				[animals addObject:animal];

				[animal release];
			}
		}
		// Release the compiled statement from memory
		sqlite3_finalize(compiledStatement);

	}
	sqlite3_close(database);

}

@end

Now I know that may look like a fair bit of code and it probably also looks quite scary! But really it is quite simple and I have tried to comment nearly every line to describe to you what the line does and why it is there.

The checkAndCreateDatabase function checks to see if we have already copied our database from the application bundle to the users filesystem (in their documents folder), if the database hasn’t already been created or it has been removed for some reason it will be recreated from the default database.

Next the readAnimalsFromDatabase function will make a connection to the database that is stored in the users documents folder, and then executes the SQL statement “SELECT * FROM animals”. It will then go through each row that is returned and it will extract the name, description and imageURL from the result and build an Animal object for each. You will see the “sqlite3_column_text” function used here, there are many more of these for returning other field types such as “sqlite3_column_int” for integers, “sqlite3_column_blob” for blobs or “sqlite3_column_value” to get an unknown value.

Now that we have the data in our array and we have it in our known format we are ready to start displaying it.

Open up the “RootViewController.m” file and edit the numberOfRowsInSection to look like the following:

SQLiteTutorialAppDelegate *appDelegate = (SQLiteTutorialAppDelegate *)[[UIApplication sharedApplication] delegate];
return appDelegate.animals.count;

What this does is it creates a link to the application delegate, and then the second line returns the size f the animals array in out Application delegate, this array was filled previously from the SQLite database.

Now in the cellForRowAtIndexPath function you will need at change it to look like the following:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }

    // Set up the cell
    SQLiteTutorialAppDelegate *appDelegate = (SQLiteTutorialAppDelegate *)[[UIApplication sharedApplication] delegate];
	Animal *animal = (Animal *)[appDelegate.animals objectAtIndex:indexPath.row];

	[cell setText:animal.name];
	return cell;
}

We pretty much just added 3 lines under the “// Set up the cell” line, the first one is the same as we added previously to access the application delegate. The second line creates a new Animal object based on the array from the application delegate, it will be used to create a row for each individual record in the database. On the final line we are just setting the text of the cell to the name field from the Animal object.

You can now run the program and you should see a table view with the 4 animals we added to the database, if you added more than my default animals you should see them in here as well.

We will now setup the AnimalViewController, open up the “AnimalViewController.h” file and edit its contents to below:

#import <UIKit/UIKit.h>

@interface AnimalViewController : UIViewController {
	IBOutlet UITextView *animalDesciption;
	IBOutlet UIImageView *animalImage;
}

@property (nonatomic, retain) IBOutlet UITextView *animalDesciption;
@property (nonatomic, retain) IBOutlet UIImageView *animalImage;

@end

What we are doing above is adding an outlet for the description and image for the Animal, we will use these later on when we link the view up.

Now open up the “AnimalViewController.m” file and add a synthesize call for for the description and image, this will go under the “@implementation AnimalViewController” line, like so:

#import "AnimalViewController.h"

@implementation AnimalViewController

@synthesize animalDesciption, animalImage;

Now it is time to make the detailed view page appear when you select a record. Open up the “AnimalViewController.xib” file from the resources folder and the interface builder should appear.

The first thing we need to do is to set the File’s Owner Class to AnimalViewController, this is done by selecting the “File’s Owner” item in the main window and then clicking Tools > Identity Inspector in the top menu, and then selecting AnimalViewController from the class dropdown.

Your inspector window should now look like this:

We are going to be using a UITextView for the description (as it will allow for word wrapping and scrolling in the case that the description is quite large) and a UIImageView to display the image. I have laid mine out like below:

Now that we have everything laid out it is time to link them all up, start by holding control and click+drag from the “File’s Owner” to the “View” objects, a little gray menu will appear and you will need to select view. Now hold control and click+drag from the “File’s Owner” to the UITextView in the layout window, you should see “animalDescription” in the popup list, select it. Repeat this process for the UIImageView and you should see animalImage appear, select it also.

Now save the interface and close the interface builder.

Nearly done! All we have to do now is to setup the code for when a user presses on a record in the table view.

Open up the “RootViewController.h” file and edit its contents to below:

#import <UIKit/UIKit.h>
#import "AnimalViewController.h"

@interface RootViewController : UITableViewController {
	AnimalViewController *animalView;
}

@property(nonatomic, retain) AnimalViewController *animalView; 

@end

We are creating an instance of the AnimalViewController to be used bu the RootViewController when a user presses on an item.

Now open up the “RootViewController.m” file and edit the top part of the file to look like below:

#import "RootViewController.h"
#import "SQLiteTutorialAppDelegate.h"
#import "Animal.h"

@implementation RootViewController
@synthesize animalView;

This will just synthesize the animalView that we just added.

First up lets set the default title of our view, to do this you need to uncomment the viewDidLoad function, and edit it to below:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Uncomment the following line to add the Edit button to the navigation bar.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

	self.title = @"My Zoo";
}

We also need to edit the didSelectRowAtIndexPath

function in this file, edit it to look like below:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic -- create and push a new view controller
	SQLiteTutorialAppDelegate *appDelegate = (SQLiteTutorialAppDelegate *)[[UIApplication sharedApplication] delegate];
	Animal *animal = (Animal *)[appDelegate.animals objectAtIndex:indexPath.row];

	if(self.animalView == nil) {
		AnimalViewController *viewController = [[AnimalViewController alloc] initWithNibName:@"AnimalViewController" bundle:nil];
		self.animalView = viewController;
		[viewController release];
	}

	// Setup the animation
	[self.navigationController pushViewController:self.animalView animated:YES];
	// Set the title of the view to the animal's name
	self.animalView.title = [animal name];
	// Set the description field to the animals description
	[self.animalView.animalDesciption setText:[animal description]];
	// Load the animals image into a NSData boject and then assign it to the UIImageView
	NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[animal imageURL]]];
	UIImage *animalImage = [[UIImage alloc] initWithData:imageData cache:YES];
	self.animalView.animalImage.image = animalImage;

}

What we are doing here is checking to see if the animalView object has already been created, if not then create it.

The next few lines are used to setup the animation (slide from right to left) and to set the actual data fields to those of the selected animal.

Now you should be ready to fire up the application and see it in all its glory.

You should see your windows looking like below.
 

5. Project Files

Here are the source files for this project: Download the project source files

If you have any questions or comments please feel free to post them here and I will try to get back to you ASAP. Also keep your eye out for my second part to the advanced RSS Reader tutorial, it will be using TouchXML, SQLite, UIWebview and more!

Popularity: 100% [?]

Well while I have been working on the Blog Tutorial I have been learning alot about the iPhone SDK, and once you get into it you will find that it is really quite easy to use. Even the strict data typing!

This tutorial will take you through the process of building your own web browser (well a quick one anyway, with a hard coded URL or hard coded HTML content). When I get a spare minute I will come back and show you how to use the toolbar at the top to add searching, links, etc.

1. Setup Your Project

I am not going to go into the detail of setting up XCode or anything like that in this tutorial as I did it in the RSS Reader Part 1 tutorial, if you don’t know how to set it up then I suggest heading over here and checking it out.

In the top menu click File > New Project and then under the iPhone OS area you will need to choose Window-Based Application.

Window-Based Application Template

Name your project WebBrowserTutorial and click “Save”

2. Adding the UIWebView to the window

In the left hand pane under the Resources folder double click the “MainWindow.xib” . You should see the interface builder fire up and it should look something like below, if you don’t see the inspector window (the third window in the screenshot below) then in the top menu click Tools > Inspector.

Interface Builder Default Screen

Now simply draw the “Web View” component from the library on the right to the window (the second box) and it should automatically resize itself to fit the screen.

Now that the view is on the screen you ned to make some connections, first you will need to hold the control key and click+drag from the Web View to the “File’s Owner” Object in the first screen. You should see the following popup:

iPhone WebView delegate Popup

Just click on the “delegate” Outlet and you are set!

Save and Close the Interface Builder.

3. The Code Behind the Beast (given it is a really small and simple beast)

First off we are going to setup our header file for the UIWebView Outlet.

Open up the “WebBrowserTutorialAppDelegate.h” file from under the Classes folder in the left hand pane, it should look like this

//
//  WebBrowserTutorialAppDelegate.h
//  WebBrowserTutorial
//
//  Created by Dean on 16/09/08.
//  Copyright __MyCompanyName__ 2008. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface WebBrowserTutorialAppDelegate : NSObject  {
UIWindow *window;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

We are going to add a UIWebView Outlet just below the “UIWindow *window” line.

The code you need to add is

IBOutlet UIWebView *webView;

What this does is it sets an UIWebView Outlet up and names it “webView” for us to use in the main controller.

Save this file and open up the “WebBrowserTutorialAppDelegate.m” file from the same classes folder.

The initial content should look something like this

//
//  WebBrowserTutorialAppDelegate.m
//  WebBrowserTutorial
//
//  Created by Dean on 16/09/08.
//  Copyright __MyCompanyName__ 2008. All rights reserved.
//

#import "WebBrowserTutorialAppDelegate.h"

@implementation WebBrowserTutorialAppDelegate

@synthesize window;

- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
[window makeKeyAndVisible];
}

- (void)dealloc {
[window release];
[super dealloc];
}

@end

We are going to add some code into the applicationDidFinishLaunching method that will be executed, you guessed it, after the application finishes lunching. Don’t you just love Apple’s function names?

Add the following code just below the “applicationDidFinishLaunching” line

// Example 1, loading the content from a URLNSURL
NSURL *url = [NSURL URLWithString:@"http://dblog.com.au"];

NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];

// Example 2, loading the content from a string
//NSString *HTMLData = @"<h1>Hello this is a test</h1>";
//[webView loadHTMLString:HTMLData baseURL:nil];

Most of the code above is pretty easy to understand, I have included two options for you to play with. The first one will load the content from a url (in this case it is http://dblog.com.au) and in the second example it is loading the content from a string, this string can come from anywhere, you could dynamically generate it, it could come from an XML string (like a RSS Feed ;-) ) or pretty much anywhere!

To get the second example to work you will need to comment out the first three lines and uncomment the second two.

You should be ready to save your code and fire your application up.

4. I didn’t see anything! You Suck!

Never fear, I did that on purpose. As you may notice I am trying to press the issue of linking the Outlet to the actual component as if you dont start doing that from the start you will soon get lost and your application development will drive you batty!

You will need to open up the “MainWindow.xib” file in the resources folder again and Control click+drag from the “Web Browser Tutorial App Delegate” Object (see the first image below) to the Webview component in your window. You should see the second window below appear, when it does select the “webView” Outlet.

Web Browser Tutorial App Delegate ObjectUIWebView Outlet

Save and Close the Interface Builder again and try to run your program again, if you used the first example you would see the screen below

dBlog.com.au on your own iPhone Web Browser
[ad]

5. Conclusion

Well that’s it for this tutorial, have a go at playing around with the layout and the different UIWebView loader options and let me know how you go. I will be writing some more articles on the UIWebView in the near future, and hopefully they will help some people get their head around the iPhone Development SDK.

6. Extra Features (added 27/09/2008)

After some requests I have added some extra tips below.
First one is to load a file from the application bundle.
Open up the “WebBrowserTutorialAppDelegate.m” file and edit the applicationDidFinishLaunching function to look like below:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
	NSString *htmlFile = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"html"];
	NSData *htmlData = [NSData dataWithContentsOfFile:htmlFile];
	[webView loadData:htmlData MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:[NSURL URLWithString:@""]]; 

    [window makeKeyAndVisible];
}

What this does is it load the UIWebView content from a local file (in our case “sample.html”).

Now make a new blank file i the resources file called “sample.html” and put the following contents in it:

<html>
<head>
<title>Sample</title>
</head>
<body>
<!-- Load Image from base64 string -->
Image Loaded from base64 string:<br/>
<img src="data:image/jpeg;base64,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" alt="2954488.jpg" /><br/>
<!-- Load Image from URL -->
Image Loaded from URL:<br/>
<img src="http://www.google.com.au/intl/en_au/images/logo.gif"/><br/>
This is the <strong>body</stron> of the text.<br/>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</body>
</html>

This is just a simple html file, but you can also embed images into the html by using their base64 value, check out http://www.abluestar.com/utilities/encode_base64/index.php for info on how to convert images into base64. By using base64 encoded strings you can build a totally self contained file with all images embedded into it.

7. Download the Project Files

I have finally added the source files for this tutorial, download it now!

Popularity: 31% [?]