2013년 12월 25일 수요일

[iOS] CoreData를 이용하여 데이터를 저장하자.

 iOS에서 SQLite 를 이용하여, 데이터를 저장하고 읽어 올 수 있는데, 그러기 위해서는 SQL문과 관련 지식이 필요합니다.
 하지만, CoreData를 이용하면, SQL에 대한 이해없이도, 비교적 간단하게 데이터를 저장할 수 있습니다. 
 SQL문을 직접사용하지 않더라도, 내부적으로 Wrapping이 되어서 SQLite에 저장하게 됩니다.

먼저 CoreData Framework을 사용하기 위해서는 해당 프로젝트에서 CoreData를 사용할 수 이도록 설정을 해줘야 합니다. 
 가장 간단한 방법은 프로젝트를 Empty Application으로 만들면서, CoreData사용을 체크하면, 저장을 수 있도록 기본 소스가 추가됩니다.
만약, Single Application으로 프로젝트를 이미 만들어서 사용하고 있다면, 해당 기능들만 추가하면 사용이 가능합니다. 
 추가하는 방법은 블로그의 "[iOS] CoreData를 사용하기 위해서 추가할 것들.."을 참고하여 주세요.

1. Data Model 추가하기.

 데이터베이스의 스키마와 같은 파일을 추가합니다. New File > Core Data > Data Model 을 선택해서 추가합니다.
 프로젝트에 Model.xcdatamodeld이 추가되었을 것입니다.
 이 파일에 저장하고자 하는 형태의 데이터 엔티티를 저장합니다.
 즉, 이 엔티티가 하나의 객체/단위로 저장이 될 것입니다.
 사용자가 앱을 실행한 시간을 저장을 한다고 생각하면, 현재 날짜를 가지는 Attribute를 아래와 같이 추가할 수 있습니다.




2. 추가한 데이터 모델을 저장소와 연결하기.

 AppDelegate에 추가된 managedObjectModel 함수에 1.에서 추가된 데이터 모델에 대한 파일 이름을 설정해 줍니다.
위에 데이터 모델이름이 프로젝트 생성할 때 "CoreData사용"으로 만들어지면 프로젝트 이름과 동일하게 만들어집니다.
그래서, 별도로 데이터모델 파일을 생성한 경우에는 그 파일을 이름을 위에 넣어야 변경이 됩니다.

3. 데이터 저장되는지 확인하기.

AppDelegate의 [-application didFinishLaunchingWithOptions:]함수에서 현재 시간을 저장하여 봅시다.
source code

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    
    NSManagedObjectContext *context = self.managedObjectContext;
    NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:@"UsageStatisticDate" inManagedObjectContext:context];
    [managedObject setValue:@"2013-12-26" forKey:@"executedate"]; //날짜는 임의로 넣었습니다.
    NSError *error;
    [context save:&error];
    
    return YES;
}

4. SQLite에 저장되어 있는지 터미널로 확인해 봅시다.

위에서 저장한 것이 정확하게 저장이 되어 있는지 확인을 해보기 위해서, iPhoneSimulator에 해당 앱이 저장된 위치를 터미널로 찾아갑니다.
(Library/Application Suport/iPhone Simulator/'버전'/Applications/'.....'/Documents/)
여기에서 sqlite3로 해당 db를 열어서 내용을 확인합니다.
위에서 해당 디렉토리에서 DBUCoreDate.sqlite라는 이름의 파일이 존재합니다.
이 파일을 sqlist3 명령어로 열어서, 저장되어 있는 테이블(.tables)과 테이블 내의 데이터를 SQL문(select * from zusagestatisticdate)로 확인을 해보았습니다.
"2013-12-26"이 들어 있는 것을 볼 수 있습니다.

5. NSManagedObject를 추가해서 저장해 봅시다.

위에 4번에서는 NSManagedObject를 받아와서, setValue를 통해서 저장을 하였는데, 해당 클래스를 만들어서 저장할 수 있습니다.
Menu > Editor > Create NSManagedObject Subclass.. 를 선택하여 클래스 만듭니다.
파일이 두개가 추가됩니다.
3.에서 저장했던 방식을 아래와 같이 수정을 합니다.

source code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    NSManagedObjectContext *context = self.managedObjectContext;
    
    UsageStatisticDate *usageDate = [NSEntityDescription insertNewObjectForEntityForName:@"UsageStatisticDate" inManagedObjectContext:context];
    usageDate.executedate = @"2013-12-26 using UsageStatisticDate class";
    
    NSError *error;
    [context save:&error];
    
    return YES;
}

위 파일에서는 Subclass를 이용해서 저장하게 됩니다.
저장한 것을 터미널에서 다시 확인을 해 봅니다.