본문 바로가기

Log (Computer)/프로그래밍

아이폰 프로그래밍 스터디 예제4

벌써 네번째다. 아직 못써본 기능들이 많지만 반이상은 써본 거 같다.

이번 예제에서는 전화번호부 앱인데 지금까지 해왔던 거와 크게 다르지 않다.

하지만 이번엔 데이터를 DB로 저장하는 방법을 택했다. sqlite3를 사용하여 구현하였다.

 
책을 보고 따라했기 때문에 책내용대로 하면 터미널로 DB 파일을 생성하고 Sqlite 에서 내용을 DB 에 테이블을 생성하고 인

서트 시키고 생성된 디비파일을 리소스에 추가시키는 코드를 구현하였다.

앱에 디비의 이름과 경로를 지정하여 사용하게 하는 메소드의 구현

- (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.isFirstTimeAccess = TRUE;

NSArray *documentPahts = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString *documentsDir = [documentPahts objectAtIndex:0];

self.DBName = @"lee.j.k.db";

self.DBPath = [documentsDir stringByAppendingPathComponent:self.DBName];

[self checkAndCreateDatabase];

    [self.window addSubview:navigationController.view];

    [self.window makeKeyAndVisible];


    return YES;

}


디비가 생성되었는지를 체크하고 없으면 생성하게 하는 메소드

-(void) checkAndCreateDatabase {

NSFileManager *fileManager = [NSFileManager defaultManager];

if([fileManager fileExistsAtPath:self.DBPath]) {

return;

}

else {

NSString *databasePathFromApp = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:self.DBName];

[fileManager copyItemAtPath:databasePathFromApp toPath:self.DBPath error:nil];

[fileManager release];

}

}


디비로부터 정보를 불러오는 메소드

-(void) readMemoFromDatabase {

sqlite3 *database;

if(self.isFirstTimeAccess == TRUE) {

self.DBData = [[NSMutableArray alloc] init];

self.isFirstTimeAccess = FALSE;

}

else {

[self.DBData removeAllObjects];

}

if(sqlite3_open([self.DBPath UTF8String], &database) == SQLITE_OK) {

const char *sqlStatement = "SELECT * FROM tblPhonebook ORDER BY MP_Index DESC";

sqlite3_stmt *compiledStatement;

if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {

while (sqlite3_step(compiledStatement) == SQLITE_ROW) {

NSInteger aIndex = sqlite3_column_int(compiledStatement, 0);

NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];

NSString *aPhoneNumber = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];

NSString *aMemo = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];

PhonebookData *pd = [[PhonebookData alloc] initWithData:aIndex Name:aName PhoneNumber:aPhoneNumber Memo:aMemo];

NSLog(@"%d / %@ / %@  / %@ ", aIndex, aName, aPhoneNumber, aMemo);

[self.DBData addObject:pd];

[pd release];

}

}

else {

printf("could not prepare statemnt: %s\n", sqlite3_errmsg(database));

}

sqlite3_finalize(compiledStatement);

}

sqlite3_close(database);

}


디비에 새로운 내용을 추가하는 메소드

-(void) writePhoneBookToDatabaseWithName:(NSString *)inputName PhoneNumber:(NSString *)inputPhoneNumber Memo:(NSString*)inputMemo {

sqlite3 *database;

if (sqlite3_open([self.DBPath UTF8String], &database) == SQLITE_OK) {

const char *sqlStatement = "INSERT INTO tblPhoneBook(MP_Name, MP_Phonenumber, MP_Memo) VALUES(?, ?, ?)";

sqlite3_stmt *compiledStatement;


if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {

sqlite3_bind_text(compiledStatement, 1, [inputName UTF8String], -1, SQLITE_TRANSIENT);

sqlite3_bind_text(compiledStatement, 2, [inputPhoneNumber UTF8String], -1, SQLITE_TRANSIENT);

sqlite3_bind_text(compiledStatement, 3, [inputMemo UTF8String], -1, SQLITE_TRANSIENT);

if(SQLITE_DONE != sqlite3_step(compiledStatement))

NSAssert1(0, @"Error while inserting into tblPhonebook. %s,", sqlite3_errmsg(database));

sqlite3_reset(compiledStatement);

sqlite3_close(database);

}

else

printf("could not prepare statemnt : %s\n", sqlite3_errmsg(database));

}

}

else {

sqlite3_close(database);

NSAssert1(0, @"Error while inserting into tblPhonebook. %s,", sqlite3_errmsg(database));

}


}


디비에 기존의 내용을 편집할때 사용하는 메소드

-(void) updatePhoneBookToDatabaseWithName:(NSString *)inputName PhoneNumber:(NSString *)inputPhoneNumber Memo:(NSString *)inputMemo {

sqlite3 *database;

if (sqlite3_open([self.DBPath UTF8String], &database) == SQLITE_OK) {

NSString* sqlStatementNS = [[NSString alloc] initWithString:[NSString stringWithFormat:@"UPDATE tblPhoneBook SET MP_Name=?, MP_Phonenumber=?, MP_Memo=? WHERE MP_Index = '%d'", self.currentMemoSQLIndex]];

const char *sqlStatement = [sqlStatementNS UTF8String];

sqlite3_stmt *compiledStatement;

if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {

sqlite3_bind_text(compiledStatement, 1, [inputName UTF8String], -1, SQLITE_TRANSIENT);

sqlite3_bind_text(compiledStatement, 2, [inputPhoneNumber UTF8String], -1, SQLITE_TRANSIENT);

sqlite3_bind_text(compiledStatement, 3, [inputMemo UTF8String], -1, SQLITE_TRANSIENT);

if(SQLITE_DONE != sqlite3_step(compiledStatement))

NSAssert1(0, @"Error while inserting into tblPhonebook. %s,", sqlite3_errmsg(database));

sqlite3_reset(compiledStatement);

sqlite3_close(database);

}

else

printf("could not prepare statemnt : %s\n", sqlite3_errmsg(database));

}

}

else {

sqlite3_close(database);

NSAssert1(0, @"Error while inserting into tblPhonebook. %s,", sqlite3_errmsg(database));

}

}

이상 기본적으로 구현되있는 코드를 사용하기위해 다른 뷰에서는 Delegate 를 이용하여 이 메소드들에 접근하여 사용하게

된다.

코드에 디비를 사용해서 구현했다고 했을 뿐이지 기존 했었던 예제들과 그리 구현하는데 큰 차이가 없다.

좀 다른게 있다고 하면 테이블뷰 셀을 구현하여 테이블뷰를 다르게 구현할 수 있다는 점인데

비어있는 xib 파일을 생성한 후 테이블뷰셀을 배치한 후

사용할 테이블뷰에 테이블뷰셀을 변수를 추가해서 연결만 시키면 되는 간단한 구조이다.