본문 바로가기

App Dev

[IOS] CRUD in swift _ CoreData

CURD (Create, Update, Retrieve, Delete)

  • 코어 데이터 (Core Data) 는 Apple IOS 에서 사용되는 그래픽  지속성 프레임워크이다.
  • 데이터를 관계형 엔티티 속성 모델 방식으로 구성하여 XML, 이진 or SQLite 저장소로 직렬화할 수 있다.
  • 코어 데이터를 사용하여 응용 프로그램의 영구 데이터를 오프라인에서 사용할 수 있도록 저장하고, 임시 데이터를 캐시하며, 단일 장치에서 응용 프로그램에 실행 취소 기능을 추가할 수 있다.
  • 코어 데이터는 스키마를 CloudKit 컨테이너에 자동으로 반영하여 단일 iCloud 계정의 여러 장치에서 데이터를 동기화한다.
  • SQL 데이터베이스와 달리 한 번 입력한 데이터만 저장할 수 있는 것이 단점이다.
  • 이전 코어 데이터는 멀티 스레딩에 몇 가지 문제가 있었지만, 코어 데이터 개발의 발전으로 멀티 스레딩과 호환이 되었다고 한다.

 

Create

let entity = NSEntityDescription.entity(forEntityName: "Users", in: context)
let newUser = NSManagedObject(entity: entity!, insertInto: context)

newUser.setValue("Abhishek", forKey: "username")
newUser.setValue("2311", forKey: "password")
newUser.setValue("21", forKey: "age")

 

Update

  • 컨텍스트를 저장하는 데 사용되는 메서드가 AppDelegate 에 이미 있지만 코드의 명시적 정의는 데이터베이스에 컨텍스트를 저장하는 데도 수행할 수 있다. 예외 처리에 도움이 되기 때문에 try - catch 블록으로 포장하는 것을 참조하는 것이 좋다.
do { 
  try context.save()      
 } catch {      
  print("Error saving")
}

 

Retrieve

  • 엔티티에 대한 NSFetchRequest 유형의 요청을 작성하고 구성한다.
  • 필요한 경우, Filter Data 에 술어를 사용한다.
  • [NSManagedObject]의 배열 형식으로 컨텍스트에서 결과를 가져온다.
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
        //request.predicate = NSPredicate(format: "age = %@", "21")
request.returnsObjectsAsFaults = false        
do {
            let result = try context.fetch(request)
            for data in result as! [NSManagedObject] 
{
    print(data.value(forKey: "username") as! String)
  }

       } catch {

           print("Failed")
}

 

Delete

  • 엔티티에 대한 요청을 수립한다.
  • 삭제할 레코드를 가져온다.
let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
let context = self.appDel.managedObjectContext!

context.del(data)
do {
try context.save()
}
catch {
    // Handle Error
}

 

CoreData Stack

  • 데이터 모델 파일을 만든 후에는 앱의 모델 계층을 공동으로 지원하는 클래스를 설정한다. 이러한 클래스를 → “CoreData Stack” 이라고 말한다.
  • CoreData 는 앱의 모델 계층을 공동으로 지원하는 클래스 집합을 제공한다고 했다.
    1. NSManagedObjectModel 인스턴스는 속성 및 관계를 포함하여 앱의 유형을 설명한다.
    2. NSManagedObjectContext 인스턴스는 앱 유형의 인스턴스에 대한 변경 사항을 추적한다,
    3. NSPersistentStoreCoordinator 인스턴스는 스토어에서 앱 유형의 인스턴스를 저장하고 가져온다.
    4. NSPersistentContainer 인스턴스를 사용하여 모델, 컨텍스트 및 스토어 코디네이터를 동시에 설정할 수 있다.


Initialize a Persistent Container

  • 일반적으로 앱이 시작하는 동안 핵심 데이터를 초기화한다.
  • 앱의 대리자에서 처음 사용할 때까지 인스턴스화를 연기할 영구 컨테이너를 lazy var 를 사용해서 만든다.
  • 사실 XCode 프로젝트를 만들 때 코어 데이터를 만들기로 선택하면 앱 델리게이트에 자동으로 포함된다.
    • 영구 컨테이너 인스턴스를 생성하여 데이터 모델 파일 이름을 이니셜라이저에 전달한다.
    • 영구 저장소를 로드하지만, 스토어가 없는 경우 이 호출을 통해 스토어가 생성된다.
class AppDelegate: UIResponder, UIApplicationDelegate {

    ...

    lazy var persistentContainer: NSPersistentContainer = {        
        let container = NSPersistentContainer(name: "DataModel")
        container.loadPersistentStores { description, error in
            if let error = error {
                fatalError("Unable to load persistent stores: \\(error)")
            }
        }
        return container
    }()

    ...
}

 

viewController 에 영구 컨테이너 참조 전달

  • 앱의 루트 뷰 컨트롤러에서 코어 데이터를 가져오고 영구 컨테이너에 대한 참조를 보유할 변수를 만든다.
import UIKit
import CoreData

class ViewController: UIViewController {

    var container: NSPersistentContainer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        guard container != nil else {
            fatalError("This view needs a persistent container.")
        }
        // The persistent container is available.
    }
}

앱 델리게이트에서 (_:didFinishLaunchingWithOptions:)에서 앱 창의 rootViewController를 앱의 rootViewController 유형으로 다운그레이드한다.

이 참조에서 루트 뷰 컨트롤러의 컨테이너 속성을 영구 컨테이너로 설정한다.

class ViewController: UIViewController {

    ...
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let nextVC = segue.destination as? NextViewController {
            nextVC.container = container
        }
    }
}

 

영구 컨테이너 하위 클래스

  • NSPersistentContainer는 하위 분류된다.
  • 하위 클래스는 데이터의 하위 집합을 반환하고 데이터를 디스크에 유지하기 위해 호출하는 함수와 같은 핵심 데이터 관련 코드를 저장하기에 편리하다.
import CoreData

class PersistentContainer: NSPersistentContainer {    

    func saveContext(backgroundContext: NSManagedObjectContext? = nil) {
        let context = backgroundContext ?? viewContext
        guard context.hasChanges else { return }
        do {
            try context.save()
        } catch let error as NSError {
            print("Error: \\(error), \\(error.userInfo)")
        }
    }    
}

 

⭐ 모델 계층을 자체 프레임워크로 요인화할 때 NSPersistentContainer 하위 클래스는 자체 번들에서 모델 파일을 찾는다.

 

'App Dev' 카테고리의 다른 글

[iOS] MVC/MVVM 패턴  (0) 2022.12.07
[iOS] 동기 및 비동기  (0) 2022.11.28
[IOS] IOS 앱 생명주기  (0) 2022.11.24