티스토리 뷰
데이터베이스 만들기
시작하기위해, FireFox와 SQLite Database Manager 플러그인이 필요합니다. 만약 없다면, FireFox 웹사이트에서 다운 및 설치 가능합니다. FireFox가 설치되면 애드온 관리자에서 SQLite Manager를 설치합시다.
SQLite Manager는 사용중인 버젼에 따라 Firefox 메뉴나 도구메뉴로부터 실행가능합니다 (그림 1).
새 데이터베이스를 만들기위해 new Database 버튼을 클릭합시다 (그림 2). 원하는 데이터베이스 이름 입력합시다. SQLite 확장자는 자동적으로 추가됩니다. 파일 저장을 확인받습니다 (당연히). 나중에 파일을 복사해야 하므로 어디에 저장하는지 기억해둡시다.
다음으로, new table 버튼을 클릭하여 (그림 3) 새 테이블을 만드는데, 역시 이름을 정해줍시다. 이 강좌에선, wineTbl 테이블과 다음의 4개의 컬럼을 쓰도록 합니다: id [primary, autoinc, integer], winename [varchar], winerating [varchar] 그리고 wineimage [blob].
이 강좌의 sake에 대해, 와인 데이터베이스와 웹으로부터 이미지들을 준비해놓을 것입니다. 테이블을 선택하고 browse & data 탭을 선택하여 데이터를 추가할 수 있습니다. 이미지 업로드 하려면 blob 필드 다음의 문서클립 아이콘을 클릭합니다. (그림 4와 그림 5).
이제 FireFox 메뉴에서 데이터베이스를 닫을 수 있으며 이 강좌에선 이후로 FireFox를 사용할 일은 없습니다.
IOS 5 프로젝트 만들기
XCode 4.2 실행하고 Single-View IOS 5 앱을 만듭시다. 이름을 부여하고 Storyboard와 ARC를 선택합시다. Git 설정하여 source control 사용여부는 알아서하고 프로젝트 만들기를 끝냅시다. (그림 6).
SQLite 설정
Frameworks 폴더를 확장하고, 프레임웍중 하나를 오른쪽 클릭하고 Show in Finder를 선택하여 프레임웍 위치를 파인더로 엽니다. libsqlite_3.0.dylib 파일을 프로젝트에 추가해야합니다 (그림 6), 사용자 폴더가 나올때까지 2또는 3단계 위로 이동합니다 (파인더 메뉴의 둘러싸고 있는 폴더로 가봅시다). 그것을 열고 lib 폴더를 엽니다. sqlite_3.0.lib를 찾을때까지 아래로 스크롤. 프레임웍 폴더로 파일이 복사되지 않게 주의하며 Frameworks에 파일을 드래그하고 참조(reference)만 만듭니다 (그림 7).
프로젝트 루트를 선택하고, 오른쪽 클릭 후 Show in Finder 선택합니다. 이 강좌의 처음에 만든 sql 데이터베이스를 위치시키고 프로젝트 헤더와 구현 파일들이 있는 프로젝트 그룹으로 복사하여 넣습니다 (그림 8).
DAO(데이터베이스 접속) 기능 설정
(File | New Group) 또는 (Context Menu | New Group)을 통해 “Model”이란 이름으로 새 그룹을 만듭니다. 두개의 Objective-C 구현 파일과 대응하는 헤더 파일들을 만듭니다. File 메뉴 또는 Context 메뉴 | New File 선택으로 Model 그룹을 선택합니다. Objective-C 노드 선택하면 Objective-C 클래스 템플릿입니다.
WineList (이 강좌를 따라하고 있다면)라는 이름, NSObject의 Subclass 선택하고 파일을 만듭니다. 같은 방법으로 다음의 파일셋을 만듭니다: MyWineList, (WinesDAO 처럼 만들지는 선택할 수 있습니다). 다시한번 NSObject의 Subclass 선택하고 파일을 만듭니다 (그림 9~10).
WineList 클래스는 WineList.h (header) 파일에 4개의 속성을 지니며, wineTbl에 있는 컬럼들은 다음과 같습니다 (그림 11):
- wineId
- wine
- rating
- photo
게터 세터 설정을 위해 WineList.m (구현) 파일을 엽니다. WineList는 4개의 @synthesize 구문을 타이핑해 넣읍시다.
- @synthesize wineId;
- @synthesize wine;
- @synthesize rating;
- @synthesize photo;
CRUD(참조/검색/갱신) 기능 만들기
CRUD는 확장의 조각입니다. 이 강좌에선 R(읽기) 작동만 구현합니다. 그럴려면 앱은 CRUD(읽기) 작동을 위한 DAO 클래스를 필요로 하게 됩니다, 만약 이미 DAO 클래시를 포함시키지 않았다면, MyWineLists 또는 무엇이든간에 선언과 구현이 작동하도록 새 Objective-C 클래스를 만듭니다. MyWineLists 헤더파일에 대해서는, sqlite3 객체와 NSMutableArray 메쏘드가 선언되었습니다 (그림 12):
- db
- getMyWines
이 객체들 구현을 위해, MyWineLists.m 파일을 엽니다. 이 파일에서는, the gut if the operations will take place.
시작을 위해 NSMutableArray 메쏘드 getMyWines 와 배열 포인터 변수 만들기:
- wineArray
다음은 아래의 NSFileManager 객체, NSString 객체, Bool 객체를 선언:
- fileMgr
- dbPath
- success
…
NSMutableArray *wineArray = [[NSMutableArray alloc] init];
@try {
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:@"IOSDB.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
...
dbPath는 파일명과 fileMgr에 SQLite 데이터베이스의 경로를 포함하여 넘겨줄 것입니다. 만약 파일이 위치되면, success 는 true 값을 가집니다. 다음은 파일이 위치되었는지와 오류를 기록하지 않는지 테스트 해봅니다. 연계 동작은 데이터베이스를 열어보려 할것입니다, Select 표현식과 sql3_stmt 설정 전에 sqlite3_open:
- sql
- sqlStatement
…
if(!success)
{
NSLog(@"Cannot locate database file '%@'.", dbPath);
}
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
{
NSLog(@"An error has occured.");
}
const char *sql = "SELECT id, Wine, Rating, Photo FROM WineTbl";
sqlite3_stmt *sqlStatement;
if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
{
NSLog(@"Problem with prepare statement");
}
...
데이터베이스가 성공적으로 열리면, sqlite3_prepare는 sqlStatement를 실행하려 할것이다. 만약 표현식이 결과셋이 반환되는 결과가 성공적으로 실행되면 NSMutableArray 필드들에 결과 값들이 설정되는 while 루프가 실행됩니다.
...
while (sqlite3_step(sqlStatement)==SQLITE_ROW) {
WineList *MyWine = [[WineList alloc]init];
MyWine.wineId = sqlite3_column_int(sqlStatement, 0);
MyWine.wine = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,1)];
MyWine.rating = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 2)];
const char *raw = sqlite3_column_blob(sqlStatement, 3);
int rawLen = sqlite3_column_bytes(sqlStatement, 3);
NSData *data = [NSData dataWithBytes:raw length:rawLen];
MyWine.photo = [[UIImage alloc] initWithData:data];
[wineArray addObject:MyWine];
}
}
@catch (NSException *exception) {
NSLog(@"An exception occured: %@", [exception reason]);
}
@finally {
return wineArray;
}
...
이것은 cRud 동작들을 잘 관리합니다. 다음단계는 IBActions 와 IBOutlets 연결들을 만들어서 UI 설정을 연관시킬것입니다. (그림 12, 13).
UI 기능 만들기
시작은 파일을 열고 자리잡기. 단독 공백 장면이 보일겁니다 (View Controller). 이 부분에서는, 4개의 라벨(UILabel)이 필요합니다: Wine Name(와인 이름)과 데이터베이스 값, NSMutableArray에 저장 될 Wine Rating(와인 평가)와 상응하는 데이터베이스 값. 이미지들에 대해서는, 장면에 UIImageView 를 드래그. 사용자 인터페이스 마지막 단계로, UIToolbar를 장면 아래에 위치시키고 포함된 버튼 이름을 Next Bottle로 변경합시다 (그림 14).
앱 종결을 위해, ViewController 헤더와 구현 파일에 몇가지 코드 추가가 필요합니다. IBAction과 IBOutlet 설정을 위해, Xcode 툴바 오른쪽 위에 있는 얼굴 아이콘 Assistant Editor를 클릭하여 storyboard 옆에 헤더 파일을 엽시다 (단축키 Command+Alt+Enter) (그림 14). 처음 label을 선택하고 헤더파의 중괄호 끝과 @end directive사이에 연결선을 드래그합시다 (Ctrl+왼쪽 마우스 버튼). 팝업이뜨면, IBOutlet 선택하고 이름은 winename로 지정합시다. 평가 정보를 포함할 두번째 label도 IBOutlet 으로 하고 이름은 winerating으로 합시다. 이미지도 같은작업 반복하여 IBOutlet 만들고 이름은 wineViewer로 합시다. 마지막으로 툴바 버튼을 드래그하여 연결하는데 IBAction으로 만들고 메쏘드 이름은 GetWineListing으로 합시다. 또한 NSMutableArray 객체도 추가합시다:
- wines
점은 연결이 되었음을 가리키는 의미로 채워져 있어야 합니다.
구현 파일을 열고 게터 세터 설정:
…
@synthesize wineViewer;
@synthesize winename;
@synthesize winerating;
@synthesize wines;
…
앱 초기화 종료시 호출되는 viewDidLoad 에서는 배열에서 초기 데이터 고정을 위해 포인터를 추가하면 앱이 어떤 정보와 index 0에 있는 이미지를 표시할 것이다.
…
- (void)viewDidLoad
{
MyWineLists * mywines =[[MyWineLists alloc] init];
self.wines = [mywines getMyWines];
[self.wineViewer setImage:((WineList *) [self.wines objectAtIndex:0]).photo];
[self.winename setText:((WineList *) [self.wines objectAtIndex:0]).wine];
[self.winerating setText:((WineList *) [self.wines objectAtIndex:0]).rating];
[super viewDidLoad];
}
...
viewDidUnload 에서는 속성들에 nil 값을 줘서 메모리에서 해제합니다
…
- (void)viewDidUnload
{
[self setWineViewer:nil];
[self setWinename:nil];
[self setWinerating:nil];
[super viewDidUnload];
}
...
마지막으로 GetWineListing 메쏘드를 사용자가 버튼 클릭시, index가 증가값을 얻고 선택된 index 번호에서 데이터를 검색하도록 구현합니다.
…
- (IBAction)GetWineListing:(id)sender {
static NSInteger currentIndex = 0;
if (++currentIndex == [self.wines count]) {
currentIndex=0;
}else{
WineList *aWine = (WineList *) [self.wines objectAtIndex: currentIndex];
[self.winename setText:aWine.wine];
[self.winerating setText:aWine.rating];
[self.wineViewer setImage:aWine.photo];
}
}
…
앱 테스트
좋습니다 이제 끝입니다. 앱 실행을 위해 실행 버튼을 클릭합시다. 앱 설치가 완료된 후 화면에 데이터와 이미지가 있어야 합니다. 다음 목록을 보기 위해 Next Bottle을 클릭해보세요.
소스코드
아래는 만들었던 다양한 파일들의 소스입니다.
WineList.m
// // WineList.m // MyWineList // // Created by Kevin Languedoc on 11/25/11. // Copyright (c) 2011 kCodebook. All rights reserved. // #import "WineList.h" @implementation WineList @synthesize wineId; @synthesize wine; @synthesize rating; @synthesize photo; //With ARC, if you selected id, you don't need to dealloc @end |
MyWineLists
// // MyWineLists.h // MyWineList // // Created by Kevin Languedoc on 11/25/11. // Copyright (c) 2011 kCodebook. All rights reserved. // #import <Foundation/Foundation.h> #import <sqlite3.h> @interface MyWineLists : NSObject{ sqlite3 *db; } - (NSMutableArray *) getMyWines; @end |
WineList.h
// // WineList.h // MyWineList // // Created by Kevin Languedoc on 11/25/11. // Copyright (c) 2011 kCodebook. All rights reserved. // #import <Foundation/Foundation.h> @interface WineList : NSObject{ NSInteger wineId; NSString *wine; NSString *rating; UIImage *photo; } @property (nonatomic,retain)NSString *wine; @property (nonatomic, assign) NSInteger wineId; @property (nonatomic, retain)NSString *rating; @property (nonatomic, retain) UIImage *photo; @end |
MyWineLists.m
// // MyWineLists.m // MyWineList // // Created by Kevin Languedoc on 11/25/11. // Copyright (c) 2011 kCodebook. All rights reserved. // #import "MyWineLists.h" #import "WineList.h" @implementation MyWineLists - (NSMutableArray *) getMyWines{ NSMutableArray *wineArray = [[NSMutableArray alloc] init]; @ try { NSFileManager *fileMgr = [NSFileManager defaultManager]; NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:@ "IOSDB.sqlite" ]; BOOL success = [fileMgr fileExistsAtPath:dbPath]; if (!success) { NSLog(@ "Cannot locate database file '%@'." , dbPath); } if (!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK)) { NSLog(@ "An error has occured." ); } const char *sql = "SELECT id, Wine, Rating, Photo FROM WineTbl" ; sqlite3_stmt *sqlStatement; if (sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { NSLog(@ "Problem with prepare statement" ); } // while (sqlite3_step(sqlStatement)==SQLITE_ROW) { WineList *MyWine = [[WineList alloc]init]; MyWine.wineId = sqlite3_column_int(sqlStatement, 0); MyWine.wine = [NSString stringWithUTF8String:( char *) sqlite3_column_text(sqlStatement,1)]; MyWine.rating = [NSString stringWithUTF8String:( char *) sqlite3_column_text(sqlStatement, 2)]; const char *raw = sqlite3_column_blob(sqlStatement, 3); int rawLen = sqlite3_column_bytes(sqlStatement, 3); NSData *data = [NSData dataWithBytes:raw length:rawLen]; MyWine.photo = [[UIImage alloc] initWithData:data]; [wineArray addObject:MyWine]; } } @ catch (NSException *exception) { NSLog(@ "An exception occured: %@" , [exception reason]); } @finally { return wineArray; } } @end |
kcbViewController
// // kcbViewController.h // MyWineList // // Created by Kevin Languedoc on 11/25/11. // Copyright (c) 2011 kCodebook. All rights reserved. // #import <UIKit/UIKit.h> @interface kcbViewController : UIViewController{ NSMutableArray *wines; } @property(nonatomic,retain) NSMutableArray *wines; @property (weak, nonatomic) IBOutlet UIImageView *wineViewer; @property (weak, nonatomic) IBOutlet UILabel *winename; @property (weak, nonatomic) IBOutlet UILabel *winerating; - (IBAction)GetWineListing:(id)sender; @end |
kcbViewController.m
// // kcbViewController.m // MyWineList // // Created by Kevin Languedoc on 11/25/11. // Copyright (c) 2011 kCodebook. All rights reserved. // #import "kcbViewController.h" #import "WineList.h" #import "MyWineLists.h" @implementation kcbViewController @synthesize wineViewer; @synthesize winename; @synthesize winerating; @synthesize wines; - ( void )didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - ( void )viewDidLoad { MyWineLists * mywines =[[MyWineLists alloc] init]; self.wines = [mywines getMyWines]; [self.wineViewer setImage:((WineList *) [self.wines objectAtIndex:0]).photo]; [self.winename setText:((WineList *) [self.wines objectAtIndex:0]).wine]; [self.winerating setText:((WineList *) [self.wines objectAtIndex:0]).rating]; [super viewDidLoad]; } - ( void )viewDidUnload { [self setWineViewer:nil]; [self setWinename:nil]; [self setWinerating:nil]; [super viewDidUnload]; } - (IBAction)GetWineListing:(id)sender { static NSInteger currentIndex = 0; if (++currentIndex == [self.wines count]) { currentIndex=0; } else { WineList *aWine = (WineList *) [self.wines objectAtIndex: currentIndex]; [self.winename setText:aWine.wine]; [self.winerating setText:aWine.rating]; [self.wineViewer setImage:aWine.photo]; } } - ( void )viewWillAppear:( BOOL )animated { [super viewWillAppear:animated]; } - ( void )viewDidAppear:( BOOL )animated { [super viewDidAppear:animated]; } - ( void )viewWillDisappear:( BOOL )animated { [super viewWillDisappear:animated]; } - ( void )viewDidDisappear:( BOOL )animated { [super viewDidDisappear:animated]; } - ( BOOL )shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } @end |
'모바일 > iOS' 카테고리의 다른 글
iOS 아이폰 아이콘 크기 안내 (0) | 2012.05.07 |
---|---|
SQLite와 Objective-C로 Insert, Update, Delete하는법 By klanguedoc (0) | 2012.05.07 |
ASIHTTPRequest의 대안 MKNetworkKit (0) | 2012.02.13 |
icon dimensions (0 x 0) don't meet the size requirements. The icon file must be 57 x 57 pixels... (0) | 2012.02.13 |
iPhone 에서 IIS7+PHP & MSSQL Server에 데이터+파일 POST (0) | 2012.02.11 |
- Total
- Today
- Yesterday
- Make Use Of
- How to geek
- 인터넷 통계정보 검색시스템
- 트위터 공유 정보모음
- 웹표준KR
- 치우의 컴맹탈출구
- Dev. Cheat Sheets
- w3schools
- Dev. 조각들
- ASP Ajax Library
- CSS Tricks
- WebResourcesDepot
- jQuery Selectors Tester
- DeveloperSnippets
- Smashing Magazine
- Nettuts+
- devListing
- 웹 리소스 사이트(한)
- Mobile tuts+
- Dream In Code
- Developer Tutorials
- CSS3 Previews
- 자북
- 안드로이드 사이드
- Code Visually
- Code School
- SQLer.com
- 무료 파워포인트 템플릿
- iconPot
- Free PowerPoint Templates
- Design Bombs
- Web Designer Wall
- 1st Webdesigner
- Vandelay Design
- 무료 벡터 이미지 사이트들
- Tripwire Magazine
- Web TrendSet
- WebMonkey
- 윤춘근 프리젠테이션 디자이너 블로그
- cz.cc 무료 DNS
- [웹하드] MediaFire
- [웹하드] DivShare
- 한컴 인터넷 오피스
- Chrome
- git
- iis
- nodejs
- Debug
- classic asp
- laravel
- Linux
- Mac
- ASP
- PHP
- JQuery
- Prototype
- Android
- javascript
- mssql
- Docker
- API
- 워드프레스
- sencha touch
- CSS
- 한글
- IE
- centos
- nginx
- IOS
- Wordpress
- 안드로이드
- JSON
- iphone
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |