헬퍼 클래스를 만들기 위해서 필요한 내용들 정리.
* MO(엔티티) : NSManagedObject
엔티티는 관계형 db의 테이블이라고 보면된다.
managed object context 는 엔티티를 구현한 객체인 NSManagedObject를 통해 각 엔티티의 데이터를 처리하게 된다.
엔티티는 각각 NSManagedObject 가 되며, 필요시 이를 상속받아 구현하면 된다.
일반적으로 MO 클래스는 엔티티 이름과 동일하게 생성한다.
엔티티 편집화면에서 Editor > Create NSManagedObject Subclass.. 를 클릭하면 모델 클래스를 만들어 준다.
NSManagedObject 객체를 상속받은 클래스를 만들고, 모델 편집화면에서 엔티티 선택후 속성창에서 클래스 이름을 입력해도 된다.
자동생성된 경우 EntityName.m(.h) 파일과 이를 확장한(카테고리) EntityName+CoreDataProperties.m(.h) 파일이 생성된다
스위프트의 경우는 EntityName+CoreDataClass.swift , EntityName+CoreDataProperties.swift 파일이 생성된다.
* 모델만들기(managed object model)
리소스폴더에 dbName.momd 를 생성한다.
dbName.xcdatamodeld 파일이 컴파일되면 리소스폴더의 dbName.momd형태로 들어가게 된다.
해당 파일로 모델 객체를 생성한다.
xcdatamodel 파일에 디자인>데이터모델>모델버전으로 버전을 추가하게 되면, xcdatamodeld로 디렉토리로 변경된다.
// 위해 해당하는 정보로 모델을 생성한다.
// dbName 은 생성한 momd 파일의 이름이다.
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"dbName" withExtension:@"momd"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsURL:modelURL];
* DB파일 저장위치 및 파일명등 정의
// db 파일명
NSString *dbFilename=[NSString stringWithFormat:@"%@.sqlite", @"dbName"];
// 폴더 위치 설정 : NSCachesDirectory, NSLibraryDirectory 등 원하는 path 로 설정한다.
NSString *basePath =
[NSSearchPathForDirectoriesInDomains( NSCachesDirectory, NSUserDomainMask, YES)
objectAtIndex:0];
// 추가 경로가 필요한경우 해당 디렉토리를 생성
NSString *dataPath = [basePath stringByAppendingPathComponent:@"DataPath"];
if( ![NSFileManager defaultManage] fileExistsAtPath:dataPath])
{
[[NSFileManager defaultManager]
createDirectoryAtPath:dataPath
withIntermediateDirectories:NO
attributes:nil
error:nil];
}
// 위 path 문자열에 db파일명을 합친다
NSString *fullPath = [dataPath stringByAppendingPathComponent:dbFileName];
// 해당 전체 path를 url 로 변경
NSURL *dbURL = [NSURL fileURLWithPath:fullPath];
* 모델로부터 저장소 코디네이터 생성(persistent store coordinator)
NSError *error = nil;
// 옵션 : 데이터에 버전정보를 포함해 마이그레이션이 필요한경우 옵션을 설정한다.
NSDictionary *options =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES] NSMigratePersistentStoresAutomaticallyOption, nil];
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil)];
코디네이터 생성
// 최초 생성한 모델객체를 사용해 코디네이터를 생성한다.
NSPersistentStoreCoordinator *coord =
[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
// 저장소 타입(SQLite) 설정
[coord addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:dbURL
options:options
error:&error];
// 해당 위치에 파일이 생성되는데, 이 파일을 백업에서 제외하려면 추가 설정한다
[dbURL setResourceValue:[NSNumber numberWithBool:YES]
forKey:NSURLIsExcludedFromBackupKey
error:&error];
* 컨텍스트생성(managed object context)
컨텍스트와 코디네이터를 연결해 놓고, 사용자는 이 컨텍스트를 통해 db 작업을 하게 된다.
ConcurrencyType : NSPrivateQueueConcurrencyType, NSMainQueueConcurrencyType
NSMainQueueConcurrencyType은 메인 쓰레드에서 실행되고, NSPrivateQueueConcurrencyType은 performBlock을 통해 실행된다. 백그라운드 처리를 위해서는 NSPrivateQueueConcurrencyType을 사용해야한다. (iOS5 이후)
// 컨텍스트 만들기
NSManagedObjectContext *moContext =
[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
// 코디네이터 지정
[moContext setPersistentStoreCoordinator:coord];
// 정책 설정
[moContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
여기까지 db를 사용하기 위한 기본적인 초기화 과정이 끝났다.
* 데이터 읽기
// 객체 이름
NSString *moName = NSStringFromClass( [MyEntityClass class] );
NSFetchRequest 생성
(두가지 형태가 있는데 둘다 MO 이름이 명시적으로 필요한데, 다른 이유가 무얼까? -_-;)
최근의 xcode 아마도 8.1?? 에서는 MO 객체 생성시 fetchRequest 라는 전역 함수를 만들어 준다.
만들어주는 내용은 2번과 같음.
1. 엔티티명으로 생성
NSFetchRequest *fetchRequest =
[NSFetchRequest fetchRequestWithEntityName:moName];
2. 단순 생성후 디스크립션 적용
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// 엔티티 객체 이름으로 디스크립션 얻기.
NSEntityDescription *entityDesc =
[NSEntityDescription
entityForName:moName
inManagedObjectContext:moContext];
Sort / Predicate
NSPredicate *predicate = [ NSPredicate predicateWithFormat:@"조건문" ];
NSSortDescriptor *sd = [[NSSortDescriptor alloc] initWithKey:@"key" ascending:YES];
// 각 정보 설정
[fetchRequest setEntity:entityDesc];
[fetchRequest setSortDescriptors:sd];
[fetchRequest setPredicate:predicate];
// 가져올 값의 개수 설정 :설정하지않으면 전체
fetchRequest.fetchLimit = 1;
// 실행
[moContext executeFetchRequest:fetchRequest error:&error];
// 블럭문을 통한 실행
NSArray *result = nil;
[moContext performBlockAndWait:^{
result = [moContext executeFetchRequest:fetchRequest error:&error];
}];
항목수 가져오기
[moContext countForFetchRequest:fetchRequest error:&error];
* 데이터쓰기
NSManagedObject
NSString *moName = NSStringFromClass( [MyEntityClass class] );
NSEntityDescription *entity =
[NSEntityDescription
entityForName:moName
inManagedObjectContext: moContext];
// 오브젝트 객체를 만든다.
NSManagedObject *mo = [[NSMnagedObject alloc]
initWithEntity:entity
insertIntoManagedObjectContext: moContext];
// 값 설정
[mo setValue:@"value" forKey:@"key"];
// 저장
[moc save:&error];
'프로그래밍 > iOS,macOS' 카테고리의 다른 글
ChildViewController (0) | 2016.10.27 |
---|---|
오토레이아웃 이것저것 / Constraint / UITextView (0) | 2016.10.25 |
커스텀객체와 인터페이스빌더 (0) | 2016.10.23 |
스토리보드 / XIB (0) | 2016.10.22 |
싱글톤 (0) | 2016.10.19 |
슬라이드메뉴 (0) | 2016.10.16 |
UITableView / UICollectionView (0) | 2016.10.16 |
파일 가져오기 (0) | 2016.10.16 |
뷰 에니메이션 (0) | 2016.10.13 |
비동기 처리 ( GCD , NSOperation ) (0) | 2016.10.13 |