4. Kết nối SQLite với Xcode - Xcode - IPhone (Phần 4)

vào lúc 02:50
Cũng như các ứng dụng khác ta có nhu cầu lưu trữ dữ liệu  và lấy dữ liệu trong một cơ sở dữ liệu. Đối với các ứng dụng của iPhone, chúng ta có thể sử dụng cơ sở dư liệu là SQLite hoàn toàn miễn phí. SQLite là một thư viện phần mềm khép kín, không cần kết nối với Server, không cần cấu hình, truy vấn dữ liệu bằng SQL. Lưu ý: các ứng dụng iPhone không thể làm việc với cơ sở dữ liệu từ xa. Sau đây sẽ giới thiệu cách sử dụng SQLite vào trong ứng dụng iPhone.

Để sử dụng SQLite trong ứng dụng của bạn, bạn không phải cài đặt bất kỳ phần mềm mới trên OSx68 của bạn. Bạn có thể sử dụng dòng lệnh để tạo ra một cơ sở dữ liệu SQL hoặc sử dụng được thêm vào trình duyệt web Firefox (bạn có thể vào địa chỉ web sau để thêm SQLite Manager: https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/), đây là phần mềm quản lý tạo cơ sở dữ liệu trong bài này sẽ dùng.
Hình 1 SQLite Manager quản lý tạo cơ sở dữ liệu SQLite

Tiếp theo là tạo cơ sở dữ liệu SQLite với tên là “AnimalDatabase.sqlite”. Tạo bảng dữ liệu với tên là “animals”. Cấu trúc các trường của bảng này được thể hiện ở hình 4-26. Sau khi tạo bảng xong ta nhập dữ liệu vào bảng.
Hình 2 Nhập dữ liệu vào bảng “animals”

Bây giờ ta tạo Project để kết nối với SQLite. Tương tự như tạo Project ở các bài trên ta tạo ứng dụng kiểu “Navigation-Based Application”. Đặt tên là “SQLiteTutorial”.

Sau khi tạo Project xong ta thêm các file và các lớp cần thiết cho dự án như sau:
Ø Bây giờ chúng ta cần tạo hai lớp, lớp đầu tiên sẽ thể hiện cho “animal”, chọn File >New File, hộp thoại New File hiển thị ra ta chọn “Cocoa Touch” ở dưới iPhone OS, chọn Objective-C class. Chọn kiểu lớp là “NSObject”. Lưu lại với tên là “Animal” và chọn Add vào Project. Lớp thứ hai cũng được tạo tương tự nhưng khác là kiểu lớp là “UIViewController” đặt tên lại là “AnimalsViewController”, và Add vào Project.
Ø Chúng ta cần tạo một file kiểu View để hiển thị chi tiết thông tin khi ta tích chọn vào một Cell trong TableView. Vào File>New File, hộp thoại hiển thị ra ta chọn User Interface dưới iPhone OS. Chọn kiểu tạo là View XIB. Đặt tên như sau: “AnimalViewController.xib”. Add vào Project.
Hình 3 Chọn tạo file View XIB với tên “AnimalViewController.xib.

Để có thể lien kết được Project với SQLite thì ta cần Add frameworks hỗ trợ kết nối với SQLite đã được IOS xây dựng sẵn. Bằng cách tích vào dấu “+” trong Build Phases để Add framework này vào.
Hình 4 Tích vào dấu “+” trong Build Phases để Add framework SQLite
Ø Sau khi bấm vào dấu “+” thì hộp thoại chọn Add framework hiển thị ra ta hãy tìm chọn đến “libsqlite3.0.dylib”
Hình 5 Chọn Add “libsqlite3.0.dylib”

Tiếp theo ta cần Add file AnimalDatabase.sqlite mà ta đã tạo ở trên vào Project.
Sau khi hoàn thành tất cả các bước trên ta chuyển sang viết code cho Project.
Ø Chọn làm việc với file “Animal.h”, ta thêm dòng lệnh sau:
#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
Ø Chuyển sang file “Animal.m” để viết nội dung của lớp với phần code như sau:
#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
Ø Bây giờ ta thiết lập để truy cập vào cơ sở dữ liệu. Chọn file làm việc tiếp là “SQLiteTutorialAppDelegate.h” và thay đổi nội dung như sau:
#import <UIKit/UIKit.h>
#import <sqlite3.h>
@interface SQLiteTutorialAppDelegate : NSObject  {
    UIWindow *window;
    UINavigationController *navigationController;
    NSString *databaseName;
    NSString *databasePath;
    NSMutableArray *animals;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) NSMutableArray *animals;
@end
Ø Ở trên khai báo các thư viện và biến để kết nối với cơ sở dữ liệu SQLite. Bây giờ chọn file "SQLiteTutorialAppDelegate.m" và thay đổi nội dung như sau:
#import "SQLiteTutorialAppDelegate.h"
#import "RootViewController.h"
#import "Animal.h"
@implementation SQLiteTutorialAppDelegate
@synthesize window;
@synthesize navigationController;
@synthesize animals; // Synthesize the aminals array
- (void)applicationDidFinishLaunching:(UIApplication *)application {
      databaseName = @"AnimalDatabase.sql";
      NSArray *documentPaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
      NSString *documentsDir = [documentPaths objectAtIndex:0];
      databasePath = [documentsDir stringByAppendingPathComponent :databaseName];
      [self checkAndCreateDatabase];
      [self readAnimalsFromDatabase];
      [window addSubview:[navigationController view]];
      [window makeKeyAndVisible];
}
- (void)dealloc {
      [animals release];
      [navigationController release];
      [window release];
      [super dealloc];
}
-(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) readAnimalsFromDatabase {
      sqlite3 *database;
      animals = [[NSMutableArray alloc] init];
      if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
                  const char *sqlStatement = "select * from animals";
                  sqlite3_stmt *compiledStatement;
                  if(sqlite3_prepare_v2(database, sqlStatement, -1,
&compiledStatement, NULL) == SQLITE_OK) {
                              while(sqlite3_step(compiledStatement) == SQLITE_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)];
                                          Animal *animal = [[Animal alloc] initWithName:aName description:aDescription url:aImageUrl];
                                          [animals addObject:animal];
                                          [animal release];
                              }
                  }
                  sqlite3_finalize(compiledStatement);
      }
      sqlite3_close(database);
}
@end
Ø Hàm checkAndCreateDatabase kiểm tra xem cơ sở dữ liệu đã được thêm vào trong thiết bị hay chưa, nếu cơ sở dữ liệu chưa được tạo ra hay nó đã được gỡ bỏ vì lý do nó sẽ được cài đặt lại từ cơ sở dữ liệu mặc định. Tiếp theo hàm readAnimalsFromDatabase để kết nối đến cơ sở dữ liệu được lưu trữ trong thư mục users documents, và sau đó thực thi câu lệnh SQL: "SELECT * FROM animals". Truy vấn để lấy dữ liệu trong bảng dữ liệu “animals”, đưa các dữ liệu này vào mảng lưu trữ animals được khai báo ở lớp “.h”.
Ø Bây giờ ta hiển thị mảng dữ liệu lên TableView. Chọn file "RootViewController.m" và chỉnh sửa numberOfRowsInSection như sau:
SQLiteTutorialAppDelegate *appDelegate = (SQLiteTutorialAppDelegate *)[[UIApplication sharedApplication] delegate];
return appDelegate.animals.count;
Ø Tiếp theo ta thay đổi hàm cellForRowAtIndexPath như sau:
- (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];
    }
    SQLiteTutorialAppDelegate *appDelegate = (SQLiteTutorialAppDelegate *)[[UIApplication sharedApplication] delegate];
      Animal *animal = (Animal *)[appDelegate.animals objectAtIndex:indexPath.row];
      [cell setText:animal.name];
      return cell;   }
Ø Tiếp theo ta cần thiết lập AnimalViewController để khi bấm chọn vào một cell trên TableView thì sẽ chuyển sang View chi tiết hơn. Chọn file “AnimalViewController.h” sửa nội dung như sau:
#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
Ø Chọn file “AnimalViewController.m” để khởi tạo biến cho lớp vừa khai báo ở trên.
#import "AnimalViewController.h"
@implementation AnimalViewController
@synthesize animalDesciption, animalImage;
Ø Bây giờ ta cần làm xuất hiện trang chi tiết khi bạn chọn một cell trên TableView. Chọn file "AnimalViewController.xib", thiết lập thuộc tính class của File’s Owner Class AnimalViewController, bằng cách chọn lên biểu tượng “File’s Owner” bấm vào Identity Inspector tương tự như Attributes giới thiệu ở bài trên, và chọn AnimalViewController từ class thả xuống.
Hình 6 Chọn thuộc tính class của File’s Owner là AnimalViewController
Ø Tiếp theo ta thiết kế View hiển thị gồm: 1 UITextView, 1 UIImageView để hiển thị thông tin chi tiết. Ta kéo thả các UI cần thiết vào View.
Hình 7 Thiết kế giao diện hiển thị chi tiết
Ø Sau khi thiết kế giao diện như ở trên thì ta tiến hành kéo thả các UI tới File’s Owner để trình điều khiển hiển thị View. Từ “File’s Owner” kéo thả tới đối tượng View. Từ “File’s Owner” kéo thả đến UITextView và chọn “animalDescription” trong danh sách hiển thị ra. Thực hiện với UIImageView và chọn “animalImage” trong danh sách hiển thị ra.
Ø Chọn file “RootViewController.h” để chỉnh sửa nội dung như sau:

#import <UIKit/UIKit.h>
#import "AnimalViewController.h"
@interface RootViewController : UITableViewController {
      AnimalViewController *animalView;
}
@property(nonatomic, retain) AnimalViewController *animalView;
@end

Ø Chọn file “RootViewController.m” để khởi tạo biến và lấy giá trị mảng lưu trữ từ cơ sở dữ liệu
#import "RootViewController.h"
#import "SQLiteTutorialAppDelegate.h"
#import "Animal.h"
@implementation RootViewController
@synthesize animalView;
Ø Tiếp theo ta cần bỏ ghi chú ở trước hàm viewDidLoad để thiết lập tiêu đề cho View chi tiết. Và sửa như sau:
- (void)viewDidLoad {
    [super viewDidLoad];
self.title = @"My Zoo";
}
Ø Cuối cùng ta cần chỉnh sửa ở didSelectRowAtIndexPath” để khi ta bấm vào cell trên TableView thì sẽ chuyển sang View chi tiết.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath :(NSIndexPath *)indexPath {
      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];
      }
      [self.navigationController pushViewController:self.animalView animated :YES];
      self.animalView.title = [animal name];
      [self.animalView.animalDesciption setText:[animal description]];
      NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[animal imageURL]]];
      UIImage *animalImage = [[UIImage alloc] initWithData:imageData cache :YES];
      self.animalView.animalImage.image = animalImage;
}
Project đã được hoàn thành và bạn có thể bấm Build and Go để chạy chương trình, và cảm nhận nó. Giao diện sẽ như sau:
Hình 8 Kết quả khi chạy Project kết nối SQLite
Hãy like nếu bài viết có ích →
Kết bạn với gisgpsrs trên Facebook để nhận bài viết mới nóng hổi