DeveloperiOS DeveloperMobile TechnologyObject Oriented TechnologyObjective CProgramming LanguageSocial MediaSocial Media Marketing

iPhone & iOS Developer ตอนที่ 11 จับ SQLite มาไว้บน UITableview

การพัฒนาแอพพลิเคชันบน iPhone หรือบนแพลตฟอร์มของ iOS สำหรับ Developer มือใหม่รอบนี้จะเป็นการใช้งาน UITableView แสดงแถวที่ดึงมาจากฐานข้อมูล SQLite อย่างง่ายหลังจากที่เราได้รู้วิธีการดึงข้อมูลจากฐานข้อมูล SQLite มาแสดงผลที่หน้าแอพพลิเคชันบน iOS ของเราได้แล้วต่อมาก็น่าจะเป็นส่วนที่สำคัญสำหรับนักพัฒนาแอพพลิเคชันที่สุดแล้วล่ะครับ นั่นคือการเชื่อมต่อฐานข้อมูล SQLite ไปแสดงผลในแถวของตาราง UITableView และส่งค่าตัวแปรไปยังหน้า DetailView เพื่อดึงข้อมูลมาปรากฏ ในรูปแบบที่เนื้อหาครบครัน หรือจะบอกว่านี่เป็นวิธีการสร้างแอพพลิเคชันเต็มรูปแบบที่ดึงข้อมูลได้จริงจากฐานข้อมูล SQLite นั่นเองครับ

วิธีการใช้งาน SQLite ร่วมกับ UITableView

ให้ลองนำแนวทางพัฒนาแอพพลิเคชันด้วย UITableView และการส่งตัวแปรจากบทเรียนบทก่อนหน้ามาพัฒนาร่วมกันครับ นั่นคือบทเรียน

ซึ่งวิธีการพัฒนาแอพพลิเคชันสามารถทำได้ดังนี้ ให้ทำการ New Project ขึ้นมาใหม่เป็น Single View Application

ทำการ New Project ขึ้นมาใหม่เป็นSingle View Application
ทำการ New Project ขึ้นมาใหม่เป็นSingle View Application

สร้างฐานข้อมูลใหม่ขึ้นมาว่า “student.sqlite” โดยใช้คำสั่ง SQL สร้างตารางชื่อ “students” ขึ้นมาโดยพิมพ์คำสั่ง

CREATE TABLE "students"(
"id" INTEGER PRIMARY KEY  NOT NULL ,
"name" VARCHAR,"email" VARCHAR,
"faculty" VARCHAR,
"detail" TEXT)

เราจะได้ตารางข้อมูลของ “students” ปรากฏขึ้นมา เพื่อนำไปใช้กับ Project ของเรา ซึ่งอาจจะต้องทำการ Insert ข้อมูลลงไปในตารางสัก 10 -20 รายการสำหรับนำไปใช้ เป็นตัวอย่าง

ตัวอย่างข้อมูลที่ใช้ในตาราง students
ตัวอย่างข้อมูลที่ใช้ในตาราง students

หากใครที่สงสัยว่าทำยังไงให้อ่านบทเรียนก่อนหน้าคือ

ไปที่หน้า Project Detail ก่ทำการเพิ่ม Framework ของ SQLite ลงไปใน Project ของเรา เลือกไปที่แถบ Build Phases ของตัว Project เพื่อทำการเพิ่ม Library ของ SQLite ลงไป ในช่อง “Link Binary With Libraries” ที่ปุ่ม “+” บริเวณด้านล่างซ้ายของแถบนี้กด “+” แล้วทำการค้นหา โดยใส่คำค้นหาว่า “SQL” จะพบไฟล์ libsqlite3.dylib และ libsqlite3.0.dylib ให้เลือก libsqlite3.0.dilib ลงไป ใน Project

เพิ่ม Library ของ libsqlite3.0.dylib ลงไป
เพิ่ม Library ของ libsqlite3.0.dylib ลงไป
มีไฟล์ libsqlite3.0.dylib ลงไปใน Project
มีไฟล์ libsqlite3.0.dylib ลงไปใน Project

ไปที่ไฟล์ AppDelegate.h ทำการประกาศ หน้า ViewController เป็น Class ตัวใหม่ขึ้นมาก่อนโดยคำสั่ง

#import 
@class ViewController;
@interface AppDelegate : UIResponder {
    UIWindow *window;
    ViewController *viewController;
}
@property (strong, nonatomic) UIWindow *window;
@end

ทำการประกาศตัวแปล เพิ่มเติมในไฟล์ Controller.h โดยเรียก Libraries ของ SQLite เข้ามาในส่วนนี้

#import 
#import 
@interface ViewController : UIViewController{
    sqlite3 *database;
}

สร้างฟังก์ชันสำหรับ ทำการเก็บข้อมูลจาก SQLite ขึ้นมาด้านล่างก่อน @end

- (void) initDatabase;
@end

เป็นการเตรียมพร้อมการดึงข้อมูลจากไฟล์ SQLite ลงไปในตัวแอพพลิเคชัน ต่อจากนั้นให้นำไฟล์ SQLite ที่เราสร้างขึ้นมาที่ชื่อว่า student.sqlite มาไว้ใน Project โดยการเพิ่ม

Add File ใหม่เข้าไปใน Project นั่นคือไฟล์ student.sqlite
Add File ใหม่เข้าไปใน Project นั่นคือไฟล์ student.sqlite

ไปที่ไฟล์ ViewController.m ทำการเพิ่มคำสั่ง initDatabase เข้าไปในไฟล์ เพื่ออ่านค่าข้อมูลจากฐานข้อมูล

- (void) initDatabase
{
	BOOL success;
	NSFileManager *fileManager = [NSFileManager defaultManager];
	NSError *error;
	NSArray *paths = NSSearchPathForDirectoriesInDomains
          (NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *documentsDirectory = [paths objectAtIndex:0];
	NSString *writableDBPath = [documentsDirectory 
           stringByAppendingPathComponent:@"student.sqlite"];
	success = [fileManager fileExistsAtPath:writableDBPath];
	if (success) 
	{
		return;
	}
	NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"student.sqlite"];
	success = [fileManager copyItemAtPath:defaultDBPath 
                    toPath:writableDBPath error:&error];
	if (!success) 
	{
	NSAssert1(0, @"Failed to create writable database file with message 
                  '%@'.", [error localizedDescription]);
	}
}

เมื่อเพิ่มคำสั่งดังกล่าวลงไปแล้ว ให้ไปเรียกใช้งานฟังก์ชันนี้ที่ Method ของ ViewDidLoad อีกที

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self initDatabase];
// Do any additional setup after loading the view, typically from a nib.
}

ต่อมาเป็นการใช้คำสั่งในการเรียกอ่านข้อมูลมาเก็บไว้ในตัวแปรชุดหนึ่ง ให้ทำการเพิ่มฟังก์ชันใหม่เข้าไปในไฟล์ DetailViewController.h อีกครั้งด้วย

@interface ViewController : UIViewController{
    sqlite3 *database;
}
- (void) initDatabase;
- (void) getStudent;

เรียกข้อมูลจากฐานข้อมูลมาแล้วให้เข้าไปเพิ่ม ฟังก์ชันการทำงานที่ไฟล์ ViewController.m อีกครั้ง

- (void) getStudent
{
	NSArray *paths = NSSearchPathForDirectoriesInDomains
           (NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *documentsDirectory = [paths objectAtIndex:0];
	NSString *path = [documentsDirectory 
          stringByAppendingPathComponent:@"student.sqlite"];
	if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) 
	{
		const char *sql = "SELECT * FROM students";		
		sqlite3_stmt *searchStatement;		
		if (sqlite3_prepare_v2(database, sql, -1, 
                 &searchStatement, NULL) == SQLITE_OK) 
		{
while (sqlite3_step(searchStatement) == SQLITE_ROW) {
NSString *name = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(searchStatement, 1)];
NSString *email = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(searchStatement, 2)];
NSString *details = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(searchStatement, 4)];
NSLog(@"Name: %@ ,Email: %@ ", name, email);
		 }
		}
		sqlite3_finalize(searchStatement);
	}
}

เพิ่มคำสั่งให้แอพพลิเคชันของเราเรียกใช้งานฟังก์ชัน getStudent() ในฟังก์ชัน Method ของ viewDidLoad()

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self initDatabase];
    [self getStudent];
}

เพียงแค่รอบนี้ มีการดึงข้อมูลมาทั้งชุดของตาราง student จากคำสั่ง “SELECT * FROM students” เพื่อทำการเรียกข้อมูลทุกรายการออกมาจากฐานข้อมูล และต่อจากนี้เราจะทำการ นำข้อมูลแต่ละชุดไปแสดงผลใน UITableView แบบทีละตาราง

ในไฟล์ ViewController.m ให้เพิ่มบรรทัดตัวแปร เป็น NSMutableArray ลงไปเพื่อดึงค่าข้อมูลจาก รายชื่อ อีเมล และ รายละเอียดของรายชื่อในตาราง student

#import "ViewController.h"
@implementation ViewController{
    NSMutableArray *listOfItems;
    NSMutableArray *listOfEmails;
    NSMutableArray *listOfDetails;
}

เข้าไปแก้ไข บรรทัดของคำสั่ง getStudent() โดยแทรกคำสั่งดังต่อไปนี้

const char *sql = "SELECT * FROM students";
sqlite3_stmt *searchStatement;
if (sqlite3_prepare_v2(database, sql, -1, 
&searchStatement, NULL) == SQLITE_OK) {
     // ตำแหน่งที่แทรกเข้าไปใหม่ 3 บรรทัด
     listOfItems = [[NSMutableArray alloc] init];
     listOfEmails =[[NSMutableArray alloc] init];
     listOfDetails =[[NSMutableArray alloc] init];

เป็นการ เริ่มประกาศให้ฟังก์ชัน getStudent() นั้นรู้จักกับตัวแปร 3 ตัวคือ listOfItems, listOfEmails และ listOfDetails ว่ามันเป็นตัวแปร Array และให้มันประกาศพื้นที่จองสำหรับเก็บข้อมูลไว้

ต่อมาให้ไปที่ตำแหน่งฟังก์ชันของ While Loop ที่เราได้ทำการเก็บตัวแปรของ แถวข้อมูลลงตัวแปรไว้นั้น ให้เพิ่มคำสั่งลงไปดังนี้

while (sqlite3_step(searchStatement) == SQLITE_ROW) 
{
NSString *name = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(searchStatement, 1)];
NSString *email = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(searchStatement, 2)];
NSString *details = [NSString stringWithUTF8String:(char *)
sqlite3_column_text(searchStatement, 4)];               
NSLog(@"Name: %@ ,Email: %@ ", name, email);
 // คำสั่งใหม่ที่เพิ่มเข้าไป 3 บรรทัด
 [listOfItems addObject:name];
 [listOfEmails addObject:email];
 [listOfDetails addObject:details];
}

เป็นการดึงข้อมูล จากการวนลูปของ ฐานข้อมูลเอาข้อมูลแต่ละแถวมาเก็บในตัวแปรใหม่ของเราทั้ง 3 ตัว จนกว่าจะหมดชุดข้อมูลที่มีในตาราง student ทั้งหมด

หลักการต่อไปที่เราจะทำคือการสร้าง UITableView ขึ้นมา และมีกระบวนการดังนี้

  • ดึงข้อมูลจากตาราง student ออกมาแถวต่อแถวมาแสดงผลผ่าน Cell ของตาราง
  • Cell ของตารางมีการเปิดไปหน้า DetailViewController เพื่อแสดงผลข้อมูลเฉพาะรายการ
  • Cell ของตารางมีการส่งข้อมูลจากฐานข้อมูลผ่าน Segue แบบปรกติ

นั่นแปลว่า เอาจะหยิบเอาบทเรียนการสร้าง UITableView จากบทเรียนก่อนหน้านี้มาใช้งาน

ขั้นตอนต่อมาให้ไปที่หน้า MainStoryBoard ทำการลากเอา UITableView ไปวางไว้บนแอพพลิเคชันของเรา

ไปที่หน้า  MainstoryBoard ลาก UITableView ไปวาง
ไปที่หน้า MainstoryBoard ลาก UITableView ไปวาง

ทำการเชื่อม UITableView โดยการกดแป้น Control ที่แป้นคีย์บอร์ดค้างไว้ คลิกและลาก UITableView ไปวางที่ไอคอนของ ViewController ข้างล่างเลือกทั้ง Delegate และ Datasource

เชื่อม dataSource และ delegate ตัว UITableView ให้เสร็จ
เชื่อม dataSource และ delegate ตัว UITableView ให้เสร็จ

ทำการวนลูปแถวบน UITableView ของตารางที่เราไปวาง แต่ให้อ้างอิงการนับจำนวนแถวในฐานข้อมูลตาราง students แทน

- (NSInteger)tableView:(UITableView *)
    tableView numberOfRowsInSection:(NSInteger)section{
    return [listOfItems count];
}

เชื่อมข้อมูลในฐานข้อมูลจากตัวแปร NSMutableArray ทั้ง 3 ตัวที่เราจับค่าทั้งหมดใส่ในตัวแปรไปแล้วมาทำงาน

- (UITableViewCell *)tableView:(UITableView *)tableView 
   cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *simpleTableIdentifier =@"Cell";
    UITableViewCell *cell=[tableView 
    dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    if(cell == nil){
        cell=[[UITableViewCell alloc] 
        initWithStyle:UITableViewCellStyleSubtitle 
        reuseIdentifier:simpleTableIdentifier];
    }
    cell.textLabel.text = 
      [listOfItems objectAtIndex:indexPath.row];
    cell.detailTextLabel.text =
      [listOfEmails objectAtIndex:indexPath.row];
    return cell;
}

ทำการ “Run” ตัวแอพพลิเคชันของเราเพื่อดูผลลัพธ์การแสดงผลข้อมูลจากฐานข้อมูลบน UITableView ว่าผิดพลาดหรือเปล่า

ทำการ "Run” ตัวแอพพลิเคชันดู
ทำการ “Run” ตัวแอพพลิเคชันดู

ต่อไป เป็นขั้นตอนที่จะทำให้แอพพลิเคชันของเราทำงานได้อย่างเต็มรูปแบบนั่นคือการ เลือกตำแหน่ง Cell บน UITableView แล้วมีการเปลี่ยนหน้าและแสดงผลข้อมูลเฉพาะแถว หรือข้อมูลแต่ละชุด ให้ทำการ New File ขึ้นมาใหม่ เป็น UIViewController subclass กด Next

เพิ่มไฟล์ใหม่เป็น UIViewController subclass
เพิ่มไฟล์ใหม่เป็น UIViewController subclass

ให้เลือก Option ข้างล่างให้เป็น และทำการ เอาเครื่องหมายในช่องที่เลือกอยู่ออกให้หมด (กรณีที่มีเครื่องหมายเลือกไว้อยู่)

เลือก Subclass Of ให้เป็น UIViewController
เลือก Subclass Of ให้เป็น UIViewController

สร้างไฟล์ DetailViewController.h และ DetailViewController.m ใหม่ขึ้นมาโดยเลือก Subclass of ให้เป็น UIViewController ไม่ใช่ UITableViewController แล้วทำวาง UILabel และ UITextView เข้าไปที่หน้า DetailViewController สร้าง Outlet ใหม่ และทำการแก้ไขที่ไฟล์ DetailViewController.h ครับ

วาง UILabel และ UITextView ลงไป
วาง UILabel และ UITextView ลงไป

เพิ่มคำสั่งประกาศ Outlet ใหม่ขึ้นไปในไฟล์ DetailViewController.h ด้วยคำสั่งชุดนี้

#import 
@interface DetailViewController : UIViewController
//ชุดข้อมูลสำหรับ UILabel
@property (nonatomic, strong) IBOutlet UILabel *dataLabel;
@property (nonatomic, strong) NSString *dataName;
//ชุดข้อมูลสำหรับ UITextView
@property (weak, nonatomic) IBOutlet UITextView *dataTextView;
@property (nonatomic, strong) NSString *dataText;
@end

ตั้งชื่อ IBOutlet ของ UILabel ขึ้นมา กำหนดตัวแปรให้กับมันว่า dataLabel และสร้าง IBOutlet สำหรับ UITextView ตั้งตัวแปรว่า dataTextView และสร้างตัวแปร String เพิ่มมาอีก 2 ตัวครับ ชื่อ dataName สำหรับเก็บค่าร่วมกับ dataLabel และสร้างตัวแปร String ชื่อว่า dataText สำหรับใช้งานร่วมกับ dataTextView

เมื่อมีการประกาศตัวแปร และ Outlet เบื้องต้นไปแล้วต่อมา ให้เลือกไปที่ไฟล์ DetailViewController.m แล้วเพิ่มฟังก์ชันของ Synthesize เข้าไปที่บรรทัดข้างล่างต่อจาก @implementation DetailViewController ด้วยคำสั่งนี้ครับ

#import "DetailViewController.h"
@implementation DetailViewController
@synthesize dataLabel;
@synthesize dataName;
@synthesize dataTextView;
@synthesize dataText;

ให้ทำการImport ไฟล์ DetailViewController.h ไปแทรกไว้บนส่วน #import ของไฟล์ ViewController.m

#import "ViewController.h"
#import "DetailViewController.h" 

กลับไปที่ MainStoryboard อีกครั้งที่ไฟล์ View Controller ตัวใหม่ที่เป็นหน้าเนื้อหา ให้คลิกที่ตัว View Controller ให้เกิดเส้นขอบสีน้ำเงินครอบแล้ว เลื่อนไปที่แถบด้านขวาในส่วนของ Identity Inspector ทำการเปลี่ยน Class ใน Custom Class ให้เป็น “DetailViewController”

คลิกให้มีกรอบสีน้ำเงินที่หน้าDetailViewController แล้วเปลี่ยน Class ให้เป็น "DetailViewController”
คลิกให้มีกรอบสีน้ำเงินที่หน้าDetailViewController แล้วเปลี่ยน Class ให้เป็น “DetailViewController”

เมื่อเลือก Class ของหน้า View controller ตัวนี้ให้กลายเป็น Class ของ DetailViewController เสร็จแล้ว ให้ทำการ Link ตัว UILabel และ UITextView ที่วางอยู่ในหน้า View Controller นี้เข้ากับข้อมูลตัวแปรโดยการคลิกที่ไอคอน View Controller ด้านล่างแล้วกดแป้นคีย์บอร์ด Control ค้างไว้ ทำการลากไปยัง UILabel เชื่อมข้อมูลเข้ากับ dataLabel และลากไปยัง UITextView เชื่อมข้อมูลเข้ากับ dataTextView

กดปุ่ม Control ที่แป้นคีย์บอร์ดแล้วทำการคลิกที่ ไอคอน ViewController สีเหลืองลากไปวางที่ UITextView และ UILabel
กดปุ่ม Control ที่แป้นคีย์บอร์ดแล้วทำการคลิกที่ ไอคอน ViewController สีเหลืองลากไปวางที่ UITextView และ UILabel

เพิ่มคำสั่งเข้าไปในไฟล์ ViewController.m คราวนี้เป็นคำสั่งในการส่ง ค่าตัวแปรผ่าน Segue ไปยังหน้า DetailViewController เพื่อแสดงผลข้อมูลที่หน้าอีกหน้าเมื่อทำการกดที่แถวของ UITableView ก่อนอื่นต้องไปที่ไฟล์ ViewController.h ก่อนเพิ่มค่าตัวแปรสำหรับเก็บค่าตัวแปรส่งผ่าน segue โดยการเพิ่มคำสั่งดังนี้

#import 
#import 
@interface ViewController : UIViewController{
    sqlite3 *database;
}
@property (nonatomic, strong) IBOutlet UITableView *sendDataTable;

อย่าลืมไป ประกาศ synthesize ที่หน้า ViewController.m บริเวณส่วนบนหรือ Header ของไฟล์

@implementation ViewController
{
    NSMutableArray *listOfItems;
    NSMutableArray *listOfEmails;
    NSMutableArray *listOfDetails;
}
@synthesize sendDataTable;

ต่อมาคือการเขียนคำสั่งให้ UITableView นั้นส่งค่าตัวแปรจากการกดที่ Cell แล้วเปลี่ยนหน้าไป โดยการใช้คำสั่งที่เพิ่มเข้าไปในหน้า ViewController.m นั้นคือคำสั่งการทำงานผ่าน Segue ให้พิมพ์คำสั่งดังนี้

- (void)prepareForSegue:(UIStoryboardSegue *)segue 
   sender:(id)sender {
    if ([segue.identifier isEqualToString:@"Cell"]) {
        NSIndexPath *indexPath = 
          [self.sendDataTable indexPathForSelectedRow];
        DetailViewController *destViewController = 
         segue.destinationViewController;
        destViewController.dataName = 
          [listOfItems objectAtIndex:indexPath.row];
        destViewController.dataText = 
          [listOfDetails objectAtIndex:indexPath.row];
    }
}

กลับไปที่หน้า MainstoryBoard แล้วไปคลิกให้ขึ้นกรอบสีน้ำเงินที่หน้า ViewController หน้าแรก ทำการกดปุ่ม Control ที่แป้นคีย์บอร์ดค้างไว้ แล้วคลิกที่ไอคอน ViewController สีเหลือง ลากไปวางที่ตัว UITableView ทำการเชื่อมเข้ากับ Outlet ของ “sendDataTable” ให้เรียบร้อย

เชื่อม UITableView เข้ากับ Outlet ของ "sendDataTable”
เชื่อม UITableView เข้ากับ Outlet ของ “sendDataTable”

ให้สังเกตว่าชื่อของ Segue ที่เราตั้งไว้ในฟังก์ชัน prepareForSegue นั้นเราตั้งชื่อว่าอะไร ในที่นี้ผมตั้งว่า “Cell” ให้ใช้ชื่อว่า Cell

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"Cell"]) {

กลับไปที่ MainStoryboard คลิกที่ ViewController ของตัวแอพพลิเคชันของเราให้เกิดเส้นขอบสีน้ำเงินปรากฏขึ้น แล้วเลือกเมนูด้านบน “Editors -> Embed In -> Navigation Controller”

สร้าง Navigation Controller ใหม่ขึ้นมา
สร้าง Navigation Controller ใหม่ขึ้นมา

เมื่อสร้าง Navigation Controller เป็นที่เรียบร้อยแล้ว ให้ทำการกดที่ Cell ของ UITableView พร้อมกับกดปุ่ม Control ค้างไว้แล้วลากจาก Cell ไปวางที่หน้า DetailViewController แล้วทำการเลือกความสัมพันธ์แบบ “Push” ตั้งชื่อ Segue ว่า “Cell”

สร้าง Navigation Controller ใหม่ขึ้นมา

ตั้งชื่อ segue ว่า “Cell” จากฟังก์ชัน prepareForSegue

ทดลอง “Run” ตัวแอพพลิเคชันของเราดูจะเห็นว่า UITableView นั้นจะดึงข้อมูลมาจาก SQLite และส่งค่าแต่ละแถวไปแสดงผลที่หน้า DetailViewController ผ่าน segue อย่างสมบูรณ์

แอพพลิเคชันของเราส่งข้อมูลจาก SQLite ไปมาระหว่าง UITableView และ DetailViewController
แอพพลิเคชันของเราส่งข้อมูลจาก SQLite ไปมาระหว่าง UITableView และ DetailViewController

ซึ่งแนวคิดในการพัฒนาแอพพลิเคชัน และเก็บข้อมูลด้วย SQLite นั้นเป็นแนวคิดพื้นฐานของแอพพลิเคชันสำเร็จรูปมากมายที่ให้เราได้เลือกใช้บน App Store อาจจะประกอบไปด้วย แอพพลิเคชันประเภทให้ข้อมูล รายการข่าวสาร แอพพลิเคชันแปลภาษา หรือข้อมูลของสถานที่ต่างๆ สินค้าต่างๆ ขององค์กร และธุรกิจนั้นๆ

สำหรับ Source Code สามารถดาวน์โหลดได้ที่

http://code.google.com/p/daydev/downloads/detail?name=UITableViewSQLite.zip

อ่านบทเรียนทั้งหมด ย้อนหลังที่

บทความการพัฒนาแอพพลิเคชันบน iPhone

Asst. Prof. Banyapon Poolsawas

อาจารย์ประจำสาขาวิชาการออกแบบเชิงโต้ตอบ และการพัฒนาเกม วิทยาลัยครีเอทีฟดีไซน์ & เอ็นเตอร์เทนเมนต์เทคโนโลยี มหาวิทยาลัยธุรกิจบัณฑิตย์ ผู้ก่อตั้ง บริษัท Daydev Co., Ltd, (เดย์เดฟ จำกัด)

Related Articles

2 Comments

  1. ของผมมันขึ้น แบบนี้อ่ะหะ
    erminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Failed to create writable database file with message 'The operation couldn’t be completed. (Cocoa error 260.)'.' เกิดจากอะไรหรอคับ.

Leave a Reply

Back to top button

Adblock Detected

เราตรวจพบว่าคุณใช้ Adblock บนบราวเซอร์ของคุณ,กรุณาปิดระบบ Adblock ก่อนเข้าอ่าน Content ของเรานะครับ, ถือว่าช่วยเหลือกัน