본문 바로가기

개발/Swift

[Swift] Core Data 알아보기 (1)

반응형

Core Data  

CoreData는 많은 양의 데이터 속에서 어떤 것을 찾을 때를 말한다. 
CoreData는 즉 SQL 데이터베이스를 말하며 객체 지향 API를 가지고 있다.
스위프트 객체처럼 보이지만 실제로는 그 스위프트 객체는 SQL 데이터베이스 안에 있는 형태다.

Xcode 안에 비주얼 매퍼라는 툴을 가지고 일치시킬 수 있다. 
모든 객체를 만들면 변수들을 매퍼 안에 만들어지는데 값은 자동적으로 매퍼가 일치시킨다. 
+ 데이터베이스의 구조- 테이블의 열은 레코드를, 행은 필드를 나타낸다.
이 작업은 보이지 않는 곳에서 일어나며 프로그래밍하는 동안에는 보이지 않는다.

코어 데이터를 이해하는데 가장 중요한 것은 NSManagedObjectContext를 사용한다는 점이다. 
NSManagedObjectContext는 코드로부터 코어 데이터에 접근하는 방법이다.
이것의 context는 key이고 이 context를 갖는 두 가지 방법이 있다.

하나는 프로젝트를 생성할 때 + use CoreData 를 누르는 것이다.
그러면 자동으로 App delegate에 컨텍스트를 주는 메소드가 사용된다.

다른 방법은 UIDocument의 서브 클래스를 생성하는 것이다. 
이건 UIDocument는 도큐멘트를 추상화하는 방법이다.
추상화함으로 전체 데이터베이스를 하나의 큰 도큐먼트로 볼 수 있다.


이제 객체처럼 보이는 데이터베이스로 접근을 시작할 수 있다.

let context: NSManagedObjectContext = ...

if let tweet = Tweet(context: context) {
    tweet.text = "140자 이내로 작성 가능합니다."
    tweet.created = Date()
    let joe = TwitterUser(context: tweet.managedObjectContext)
    tweet.tweeter = joe
    tweet.tweeter.name = "Joe Schmo"
}

예를 들어 트윗을 만들어보자.
이 context는 데이터베이스에 대해 알려준다.
tweet.created와 joe라는 사용자도 트윗과 같은 context에 생성할 수 있다.

context.delete(tweet)

context를 통해 객체를 지울 수도 있다.

do {
    try context.save()
} catch {
    // error
}

UIDocument를 사용해 context를 찾는데 접근하면 어떤 변화를 주어도 자동으로 저장된다.
SQL 데이터베이스에 어떤 것을 저장한다면 SQL 에러가 생길 수도 있고, 파일 시스템이 꽉 차 있을 수도 있으니 에러문을 활용하자.

객체를 찾을 때는 이렇게 한다.

let request: NSFetchRequest<TwitterUser> = TwitterUser.fetchRequest()

// 24시간 전에 트윗한 사람 찾기
let yesterday = Date(timeIntervalSinceNow: -24*60*60) as NSDate
request.predicate = NSPredicate(format: "any tweets.created > %@", yesterday)

// 유저 이름으로 정리하기
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)

let context: NSManagedObjectContext = ...
// context가 일치하는 것을 불러오도록 시킨다.
let recentTweeters = try? context.fetch(request) 

Predicate는 텍스트에서 찾고자 하는 것을 명시하는 방법을 속성화 시키는 것이다. 

 

CoreData 생성

 

Coredata 파일 생성하기

파일을 생성하고 나면 프로젝트에 ~.xcdatamodeld 라는 파일이 들어왔을 것이다.
CoreData를 설정하기 전, AppDelegat에 아래 코드를 추가해준다.
(프로젝트 생성 시 CoreData를 체크하지 않았다면 해주어야하는 작업들이다.)

// MARK: - Core Data stack 

lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "xcdatamodeld 파일 이름")
    container.loadPersistentStores(completionHandler: { (storeDescirption, error) in
        if let error = error as NSError? {
             fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()


// MARK: - Core Data Saving support 

func saveContext () {
    let context = persistentContainer.viewContext
    if context.hasChanges {
        do {
            try context.save()
        } catch {
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

xcdatamodeld 파일로 돌아와 엔티리를 만들어보자.

Entity는 왼쪽 아래 Add Entity 버튼을 누르면 추가할 수 있다. 

 


Attribute를 추가하려면 오른쪽 아래 Add Attribute 버튼을 클릭하자.
Attribute 설정을 위해 바로 옆의 Editer style 트리 모양을 클릭하자.

Type을 설정하지 않으면 에러가 뜨는데, Attribute는 반드시 특정한 타입을 가져야하기 때문이다.
Undefined를 클릭해서 원하는 타입을 선택해준다.

타입 중 Transformable은 어떤 것이든 데이터 베이스에 저장할 수 있게 해주는 변경 가능한 타입이다.
데이터로 변환하거나 반대로도 변환해주는 것이 가능하기에 이를 설정할 다른 작업이 별도로 필요하다.

화살표가 가리키는 Editer Style을 클릭하면 더 직관적으로 볼 수 있다.

이들에게 관계를 줄 수 있는데, 스토리보드에서 하듯이 Ctrl + 드래그로 줄 수 있다. (드래그는 어느 방향이든 상관없다.)
관계를 만들어주고 오른편의 Inspector로 설정을 해보자.

Tweet는 트윗 하나를 말하고, TwitterUser는 여러 Tweet을 가질 수 있는 저장소다.
TwitterUser의 관계를 클릭해서 Inspector 창의 Type에 To One을 To Many로 변경해준다. 
(위의 관계 이름이 바뀐 것은 이름을 변경해준 것이다. 더블 클릭하면 쉽게 바꿀 수 있다.)

데이터베이스에 있는 객체는 NSManagedObject로 대표된다.
Tweet의 관계는 NSManagedObject로 설정되지만, 
TweeterUser의 관계는 NSManagedObject의 NSSet으로 설정된다.

NSSet은 Objective-c버전의 Set인데 제네릭도 아니고 타입도 없는 Any타입이다. 
NSManagedObject의 NSSet를 코드로 Set로 캐스팅할 수 있다.

관계를 지웠을 때는 오른쪽 옆의 Inspector - Delete Rule 칸으로 어떻게 처리할 것인지 설정할 수 있다.
Nullify는 관계가 지워져도 Tweet는 데이터베이스에 남고, Tweet의 관계인 array만 nil로 설정되는 것이다.
Cascading는 한 쪽을 삭제하면 연결된 모든 것들이 함께 지워지는 것이다.

CoreData의 첫번째 Entity, Attribute, RelationShip 정의가 끝났다.
CoreData를 코드로 옮겨주는 작업은 다음 장에서 진행하겠다.

반응형

'개발 > Swift' 카테고리의 다른 글

[Swift] 문자열 다루기  (0) 2021.03.31
[Swift] Core Data 알아보기 (2)  (0) 2021.03.02
[Swift] File System  (0) 2021.03.01
[Swift] 객체 저장 - Archiving  (0) 2021.02.28
[Swift] 객체 저장 - UserDefaults  (0) 2021.02.28