Tuesday, October 26, 2010

IPhone programming tutorial - database tutorial

What we will learn?
This tutorial will show you the basic of database programming on IPhone . We are going to use FMDatabase wrapper which simplifies the use of sqlite library. using FMDatabase we are going to create a program which populates a table with the database information and when a table cell is clicked the program will display additional information extracted from the database. 



Things we will cover in this tutorial
We are going to learn the following thing: 
-start a new project and add things we need to add database to our project
-learn a bit about FMDatabase and the functions available for us.
-extract information from the database

Source code for the project:

lets begin:

1. download the following files:




 You downloaded here the wrapper functions for sqlite and the database we will use for the tutorial.
I'm not gonna show you in this tutorial how to create the database and if you want to create your own database u can find information on the subject in the following site: 

Our database consists of 3 columns the first one is the primary key which is a unique index for every row in the database. the second one is a string of names of students, and the third ont is integer for the students id's.
the first column name is: 'pk', the second column name is: 'name' the third: 'id'

2. launch XCode
3. start a new project 
4. choose navigation based application and name it:'database1'
5. right click classes in the groups and files and choose add -> new group
6. name the group database and copy the FMDatabase files to the new folder you just created
make sure you check the check box that says copy the files...(if needed)
7. copy students7.sqlite to the resource
make sure you check the check box that says copy the files...(if needed) 
right click frameworks in the groups and files choose add->existing frameworks
choose libsqlite3.0.dylib from the list and press add. if you cant find it you need to manually find it so press add other goto developer/platforms/iphoneos.platform/developer/SDKs/iPhoneOS3.2sdk/usr/lib
and choose the file i mentioned earlier.
next we will create the openning window
8. right click classes choose add new files
9. choose UIViewController subclass and make sure only  'with xib...' check box is selected
10. name the class: OpenWinViewController
11. move the xib file that was created to the resources group
change the OpenWinViewController.h to look like this: 
//
//  OpenWinViewController.h
//  database1
//
//  Created by Yariv Katz on 10/26/10.
//  Copyright 2010 YKSoftware. All rights reserved.
//

#import


@interface OpenWinViewController : UIViewController {

}

-(IBAction)btnNamesClick:(id)sender;

@end




12. change the OpenWinViewController.m to look like this: 
//
//  OpenWinViewController.m
//  database1
//
//  Created by Yariv Katz on 10/26/10.
//  Copyright 2010 YKSoftware. All rights reserved.
//

#import "OpenWinViewController.h"
#import "RootViewController.h"

@implementation OpenWinViewController

-(IBAction)btnNamesClick:(id)sender{
    RootViewController* viewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];
   
    [self.navigationController pushViewController:viewController animated:YES];
    [viewController release];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
   
    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


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


@end

13. double click the OpenWinViewController.xib file that was created and drag a button
and connect the touch up inside event to btnNamesClick event
14. now double click MainWindow.xib and change the navigation controller child to be the new class we just created and the nib to be the nib we created.
we will now create the NSObject that will correspond to a row in the database
15. right click classes and choose add->new file
16. choose here objective c class and make sure u select subclass of nsobject.
17. name the classes: 'singleStudent'
18. change the singleStudent.h to look like this: 
//
//  singleStudent.h
//  database1
//
//  Created by Yariv Katz on 10/26/10.
//  Copyright 2010 YKSoftware. All rights reserved.
//

#import


@interface singleStudent : NSObject {
    int studentId;
    int pk;
    NSString* strName;
}
@property (nonatomic,assign)int studentId;
@property (nonatomic,assign)int pk;
@property (nonatomic,retain) NSString* strName;

-(id)initWithData:(int)intPk :(NSString *)name :(int)aId;

@end
19. change the singleStudent.m  to look like this: 
//
//  singleStudent.m
//  database1
//
//  Created by Yariv Katz on 10/26/10.
//  Copyright 2010 YKSoftware. All rights reserved.
//

#import "singleStudent.h"


@implementation singleStudent
@synthesize studentId,pk,strName;

-(id)initWithData:(int)intPk :(NSString *)name :(int)aId{
    self.studentId = aId;
    self.strName = name;
    self.pk = intPk;
    return self;
}

@end






20. change the database1appdelegate.h to look like this: 
//
//  database1AppDelegate.h
//  database1
//
//  Created by Yariv Katz on 10/25/10.
//  Copyright YKSoftware 2010. All rights reserved.
//

#import
#import "FMDatabase.h"

@interface database1AppDelegate : NSObject {
   
    UIWindow *window;
    UINavigationController *navigationController;
    NSMutableArray* aryDatabase;
    NSString* databaseName;
    NSString* databasePath;
    FMDatabase* db;
}

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

@end

21. change the database1appdelegate.m to look like this
change this function: 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {   
   
    // Override point for customization after application launch.
   
    // Add the navigation controller's view to the window and display.
    [self updateNames];
    [self checkAndCreateDatabase];
    [self readWordsFromDatabase];
    [window addSubview:navigationController.view];
    [window makeKeyAndVisible];

    return YES;
}

add these three new function to database1appdelegate.m:
-(void)updateNames{
    databaseName = @"students7.sqlite";
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
}



-(void) checkAndCreateDatabase{
    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    success = [fileManager fileExistsAtPath:databasePath];
    if(success) return;
    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
    [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
    [fileManager release];
}


-(void) readWordsFromDatabase {
    [self updateNames];
    db = [FMDatabase databaseWithPath:databasePath];
    aryDatabase = [[NSMutableArray alloc] init];
    [db setLogsErrors:TRUE];
    [db setTraceExecution:TRUE];
    if (![db open]) {
        NSLog(@"Could not open db.");
        return;
    }else {
        NSLog(@"oooooooohooo. DB Open....");
    }
    FMResultSet *rs = [db executeQuery:@"select * from student"];
    while ([rs next]) {
        int aID = [rs intForColumn:@"id"];
        int intPk=[rs intForColumn:@"pk"];
        NSString* aName = [rs stringForColumn:@"name"];
        NSLog(@"%s",aName);
        singleStudent* sStudent = [[singleStudent alloc] initWithData:intPk :aName :aID];
        [aryDatabase addObject:sStudent];
        [sStudent release];
    }
    [db close];
}

add also the following imports:
#import "database1AppDelegate.h"
#import "RootViewController.h"
#import "singleStudent.h"

further explanation about the code we added you can find on the video
22. goto RootViewController.m and change the following function to look like this: 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    database1AppDelegate *appDelegate = (database1AppDelegate *)[[UIApplication sharedApplication] delegate];
   
    return [appDelegate.aryDatabase count];
}

23. change in the same file the following function: 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   
    static NSString *CellIdentifier = @"Cell";
   
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    database1AppDelegate *appDelegate = (database1AppDelegate *)[[UIApplication sharedApplication] delegate];
    singleStudent* sStudent =(singleStudent *) [appDelegate.aryDatabase objectAtIndex:indexPath.row];
    cell.textLabel.text = [sStudent strName];
    return cell;
}

24. change the foolowing function in the same file to look like this: 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    StudentViewController* viewController = [[StudentViewController alloc] initWithNibName:@"StudentViewController" bundle:nil];
    self.title =@"Names";
    database1AppDelegate *appDelegate = (database1AppDelegate *)[[UIApplication sharedApplication] delegate];
    singleStudent* sStudent = [appDelegate.aryDatabase objectAtIndex:indexPath.row];
    [self.navigationController pushViewController:viewController animated:YES];
    [viewController.lblName setText:[sStudent strName]];
    [viewController.lblID setText:[NSString stringWithFormat:@"%i",[sStudent studentId]]];
    [viewController release];
}

25. add the following imports to the same file above: 
#import "RootViewController.h"
#import "database1AppDelegate.h"
#import "singleStudent.h"
#import "StudentViewController.h"

26. right click classes choose add new file and choose UIViewController subclass and make sure only the xib add xib check box is marked
27. name the new class: 'StudentViewController'
28 change the StudentViewController.h to look like this: 

//
//  StudentViewController.h
//  database1
//
//  Created by Yariv Katz on 10/26/10.
//  Copyright 2010 YKSoftware. All rights reserved.
//

#import


@interface StudentViewController : UIViewController {
    UILabel* lblName;
    UILabel* lblID;
}

@property(nonatomic,retain)IBOutlet UILabel* lblName;
@property(nonatomic,retain)IBOutlet UILabel* lblID;

@end



29. change the StudentViewController.m to look like this: 

//
//  StudentViewController.m
//  database1
//
//  Created by Yariv Katz on 10/26/10.
//  Copyright 2010 YKSoftware. All rights reserved.
//

#import "StudentViewController.h"


@implementation StudentViewController
@synthesize lblName,lblID;




- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
   
    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


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


@end

30. double click the StudentViewController.xib and add two labels connect the upper one to lblname and the lower one to lblID.
all done you can launch and play with your new program. 
for full source code: 


22 comments:

  1. Hey,

    Your link does not work for the full source good and also not for the FMdatabase,
    I really like your tutorial so i want to make it, but do i really need to have the FMdatabase to complete this tutorial?

    Robi

    ReplyDelete
  2. Hi Robi try right clicking the link and choose download link
    this works for me.
    cheers

    ReplyDelete
  3. It doesnt work, can forward the zip to my by email,
    r.urban@kobelcowelding.nl

    ReplyDelete
  4. Sample not not Working! I only see a black screen!

    ReplyDelete
  5. A great tutorial ywarezk, but as Robi says the link does not work. Could you also forward the zip to my email chrissy [at] xs4all [dot] nl Cheers and thanks!

    ReplyDelete
  6. I have a question about increasing the value added UISearch in a manner which is to be. Working together.

    ReplyDelete
  7. Plz Plz guys forward the full source code and fmdaabase zip to me too!!!! anybody plz....my job is at stake.. i wil be fired if i cant do this.. i m working on a smilar project .... my id is mushtaque87@gmail.com

    ReplyDelete
  8. Can someone please forward me a copy of source code please.
    jimmy88.ie@gmail.com

    ReplyDelete
  9. Thanks for this tutorial. It's great overall, but I noticed a couple of issues with the text on this page:

    1. You have a few instances of #import by itself on a line, because the angle brackets aren't html-encoded.

    2. In the steps, you never mention creating the StudentInfoViewController class. It's in the video, but not in the text.

    ReplyDelete
  10. Please forward me a copy of source code please.
    mikekam88@hotmail.com

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete
  12. Same here can someone send me a copy of FMDatabase.zip
    students7.sqlite
    please~
    chen_910701@hotmail.com

    ReplyDelete
  13. The Full Source Code isnt working, xcode gives me like 30 errors, please help!

    ReplyDelete
  14. but its working on my ipod without errors.... It it possible to add database files within the app???

    ReplyDelete
  15. Same here can someone send me a copy of FMDatabase.zip
    students7.sqlite
    please~

    ram.agrawal0786@gmail.com

    ReplyDelete
  16. i need the source code of this tutorial , please send it to my email
    rahman231@gmail.com

    many thanks.

    ReplyDelete
  17. hi.
    I'VE TRIED TO RUN THIS THING BUT THE SCREEN WAS BLACK...
    CAN SOMEBODY HELP ME PLEASE....

    ReplyDelete
  18. Hey. its absolutely working fine. You should update it with insert,update and delete queries.

    ReplyDelete
  19. can I please get the source code? dale.magnin@gmail.com

    ReplyDelete
  20. i need the source code and the fmdatabase too please thanks much

    ReplyDelete
  21. where can I download the source code?

    ReplyDelete
  22. A complete solution and deep info about iphone programming .
    Development is as much about the workflow as much as it is about the code. and its cool to start learning iphone through this way.

    learning PHP through this way.
    iphone developers

    ReplyDelete