하루를살자

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

iOS

[iOS] CoreData 를 배워보자 - 2

Kai1996 2022. 10. 14. 23:54

목차 

- NSManagedObject SubClass 

- CoreData Stack (Persistent Store, Persistent Store Coordinator)

- 예제

NSManagedObject SubClass 

저번시간에..

Entity 를 정의하고 데이터를 생성하는 과정에서 아래와 같이 프로퍼티 명을 일일히 적어 주고 fetching 해올시에도 Casting 작업을 따로 해줘야했었다. 

//Add Data
let person = NSManagedObject(entity: entity, insertInto: persistentContainer.viewContext)
person.setValue(players.key, forKey: "name")
person.setValue(players.value, forKey: "goalScore")

//Fetch Data 
 let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Player")
    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)") 
          }
        }
      }
    } catch {
      print("there was a fetch error! ")
    }
    return true
  }

NSManagedObject SubClass 를 사용하면 위와 같은 불편함을 덜어낼수 있는데 어떤식으로 작동하는지 살펴보자 

 

Xcode 를 사용해서 NSManagedObject SubClass 생성하기 

생성방법

Editor -> Create NSmanageObject Subclass 를 선택 하면 보이는것과 같이 두개의 파일이 생성되는것을 볼수 있다. 

 

- Player + CoreDataClass : Entity 이름과 같은 Class 를 생성해준다.

  👉 사용자가 직접 수정할수 있어서 커스텀 메소드 를 명시할수 있다.

- Player + CoreDataProperties : Attribute 을 각각의 Property 로 타입에 맞게 생성해준다. 

  👉 자동으로 생성된 CoreData  정보가 들어가있다. 사용자가 Entity 모델을 수정할시 이 파일에 국한해서 Attribute 가 변경된다.

*주의할점: Core Data 사용 시 entity의 Codegen 옵션 중 Class Definition 옵션은 Core Data에 의해 코드(.CoreDataProperties, .CoreDataClass)가 생성되지만 파일이 생성 되지는 않는다 (하지만 Entity 명을 소스코드에 사용할수 있음).  🛠 Manual/None 으로 설정!

 

CoreData Stack (Persistent Store & Persisten Store Coordinator) 

CoreData Stack

Persistent store

- Persistent store 는 NSManagedObjectContext 로 부터 전달 받은 가장 마지막의 요청 결과로, 실질적으로 Disk 에 저장 되어 있는 데이터 공간 입니다. 3개의 파일 타입  (binary, XML, SQLite) 으로 저장 가능하고 In-memory (휘발성) 저장도 지원합니다. 

 

- 또한 각각의 Persistent Store 의 옵션(예를들면 read-only, 저장되어지는 타입) 을 따로따로 지정해서 사용해야하는 어플리케이션 같은경우엔 여러개의 persistent store 를  가질수있게 됩니다. (더 자세한 정보는 여기를 참조해주세요) 

 

- Store 안에 있는 Entity 들은 Mananged Object Model 에서 정의 된 것과 같습니다. 만약 Model 에 변경이 있다면 원본 데이터 에 접근 불가하기 때문에, 변경이전에 Store 에 있는 데이터들의 format 을 변경 해야합니다. 

Persistent Store Coordinator

- Persistent Store Coordinator 는 Persistent Store 를 Managed Object Context 에서 부터 온 요청 으로 부터 저장/응답 해주는 다리 역할을 합니다. 만약 어떤 Store 인지 명시 해주지 않을시 모든 Store 의 데이터를 가지고 오게 됩니다. 

 

 


 NSManagedObject SubClass 를 사용해서 데이터 생성 하기 

- Player 가 이제 NSManagedObject 를 상속 받기 때문에 SetValue 를 사용하지 않고 프로퍼티를 설정해줄수 있게됩니다. 

public class Player: NSManagedObject {

}

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

for player in goalScore {
      let person = Player(entity: entity, insertInto: AppDelegate.persistentContainer.viewContext)
      person.name = player.key
      person.goalScore = player.value
}

 

 NSManagedObject SubClass 를 사용해서 데이터 Fetching 하기 

- Player + CoreDataProperties 에 아래와 같이 NSFetchRequest 를 만들어 주어 따로 Request 를 만들 필요 없이 이 함수를 사용하면됩니다. 

extension Player {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Player> {
        return NSFetchRequest<Player>(entityName: "Player")
    }

    @NSManaged public var name: String?
    @NSManaged public var goalScore: Int16

}

//Fetching Logic
let fetchRequest = Player.fetchRequest()
 do {
      let players = try AppDelegate.persistentContainer.viewContext.fetch(fetchRequest)
      data = players
      
    }catch {
      print("Not Able to fetch Player Data!")
 }

화면 

 

Comments