하루를살자

[iOS] CoreData 를 배워보자 -1 본문

iOS

[iOS] CoreData 를 배워보자 -1

Kai1996 2022. 10. 14. 16:54

목차

  • CoreData 란
  • Modeling Data
  • Add records
  • Fetch records
  • 예제

CoreData 란?

  • CoreData 는 어플리케이션의 Object graph, 및 persistence 관리를 해주는 프레임워크이다.
  • Object graph Management = Object graph 는 DB 에 정의된 스키마 처럼 정의된 클래스들의 관계를 말한다.
  • Persistence Management = 완성된 Object graph 가 나중에 어플리케이션에 사용될수 있도록 fetching 및 저장 하는 기능을 관리 한다.

Modeling Data

Data Object 를 만들기 위해서는 CoreData 의 Entity 와 Attribute 를 설정해주어야한다. 클래스나 스트럭처를 만드는것과 같이 타이틀과 프로퍼티를 원하는 타입과 함께 설정해준다.

여기서 NSManagedObjectModel, NSManagedObject, NSManagedObjectContext 라는 개념을 먼저 알아보자.

- NSManagedObjectModel = 개체(Entity), 속성 (Attribute) 리스트 와 유효성 검증, 관계를 포함한다. (Xcode 에서 모델 편집기를 이용해서 생성가능)

- NSManagedObject = 하나의 데이터 Record 를 말한다. (코어 데이터 상에서 실제 정보를 담고있는 객체를 의미한다)
- NSManagedObjectContext = workspace 같은 개념으로 여러개의 NSManagedObject 들을 포함한다. 이녀석을 사용해서 데이터를 생성, 저장, 가져오는 작업을 수행한다.

Adding Data

  • 1.0 NSEntityDescription 을 이용하여 Entity 의 타입을 특정한다.
  • 2.0 Entity 의 프로퍼티를 기반으로 하여 NSManagedObject 를 생성한뒤 NSManagedObjectContext 를 사용하여 데이터를 넣어준다.
  • iOS10+ 부터 NSPersistentContainer 라는 클래스가 추가 되었는데, 이는 NSManagedObjectModel, NSPersistentStoreCoordinator, NSManagedObjectContext 를 포함한 컨테이너 역할을 한다. 프로퍼티인 viewContext 를 사용하면 NSManagedObjectContext 를 사용하여 작업을 main queue 에서 진행하게된다. (NSPersistentStoreCoordinator 는 NSManagedObjectContext 의 요청을 수행하는데, context 와 persistent store 간의 커뮤니케이션 역할을 한다는데.. 차차 알아가보도록 하겠습니다)

Fetch Data

  • 1.0 어떤 Entity 의 정보를 가져올건지에 대한 NSFetchRequest 를 생성한다.
  • 2.0 NSFetchRequest 를 실행할때 많은 옵션(sorting, searching 등) 을 주고 원하는 데이터를 받아올수 있다.

Example)

해외 축구 선수 골 순위 NSManagedObjectModel 설정

1.0 프로젝트를 CoreData 를 포함시켜서 하나 만든다. (*Project 를 만들때 CoreData 를 포함시키면 AppDelegate 에 CoreData stack 이 자동으로 생성된다.)
2.0 CoreData 에서 Entity 추가, 타이틀과 Attribute 를 설정시켜준다.

데이터 넣기

1.0 NSEntityDescription 을 이용해서 어떤 Entity 의 데이터를 생성할건지 명시해준다.

guard let entity = NSEntityDescription.entity(forEntityName: "Player", in: persistentContainer.viewContext) else {
      fatalError("could not find entity")
}

2.0 persistentContainer 의 NSManagedObjectContext 를 사용하여 entity 을 인스턴스 화 시키고, 각 프로퍼티에 값을 setValue 를 사용하여 설정합니다.

let goalScore: [String:Int] = ["엘링 홀란":15,"해리 케인":8,"호베르투 피르미누":6, "알렉산드르 미트로비치":6, "필 포든":6, "이반 토니":6, "제임스 메디슨":5, "레안드로 트로사르":5, "가브리엘 제주스":5, "윌프레드 자하":4]
for players in goalScore {
      let person = NSManagedObject(entity: entity, insertInto: persistentContainer.viewContext)
      person.setValue(players.key, forKey: "name")
      person.setValue(players.value, forKey: "goalScore")
}

 

데이터 불러오기

1.0 어떤 Entity 의 정보를 가져올건지에 대한 NSFetchRequest 를 생성한다. 

  //어떤 타입의 Request 인지 명시를 하지 않을때
  let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Player")
  
  //Player 타입의 Request 인것을 명시
  let fetchRequest = NSFetchRequest<Player>(entityName: "Player")

2.0 viewContext 의 fetch 메소드를 사용하여 특정 Entity 의 데이터를 아래와 같이 받아온다. 

 //어떤 타입인지 명시하지 않을경우 옵셔널 체이닝으로 프로퍼티가 어떤 타입인지 명시 해주어야한다. 
 do {
      if let results = try persistentContainer.viewContext.fetch(fetchRequest) as? [NSManagedObject] {
        for result in results {
          if let goalScore = result.value(forKey: "goalScore") as? Int, let name = result.value(forKey: "name") as? String {
            print("\(name) : \(goalScore)") //The result returns in unsorted order,
          }
        }
      }
    } catch {
      print("there was a fetch error! ")
    }
    
   //어떤 타입인지 명시할경우
   do {
      let results = try persistentContainer.viewContext.fetch(fetchRequest)
      for result in results {
        if let goalScore = result.value(forKey: "goalScore") , let name = result.value(forKey: "name")  {
          print("\(name) : \(goalScore)") //The result returns in unsorted order,
        }
      }
    } catch {
      print("there was a fetch error! ")
    }

 

결과 

-  Persistent Store 안에 데이터들은 순서대로 저장되어 있지 않기 때문에  현재 결과는 골순위 대로 나오지 않고 섞여서 나오고 있다 (Dictionary 로 데이터를 선언해서 Insert 할때부터 순서가 있진 않지만..). 따라서  Fetching 할시에 sorting 옵션을주어야 한다. (이건 다음시간에 계속..) 

 

Comments