이번에 프로젝트 하면서 CoreData를 사용했다. 처음 만들고 사용하는데는 문제가 없지만
중간에 컬럼을 추가해서 사용해보니 업데이트 시 문제가 되었다. ( 컬럼 추가는 별다른 문제가 없다. )
해결법과 사용법을 정리해서 올려둔다.
일단 간단한 정리
1. 새 프로젝트라면 Use Core Data 에 체크해서 만들고
2. 기존 프로젝트 추가면 Command + N을 눌러 Data Model 추가.
---
3. .xcdatamodeld 파일에서 "Add Entity" 를 한다. Entity 이름은 중요합니다. 테이블 이름
4. 이제 Attributes 추가하고.. 등등 테이블을 만듭니다.
5. 중요: 우측의 인스펙터를 보면 "Codegen" 영역이 "Class Definition" 이라고 되어 있습니다.
여기를 그냥 사용하면 비즈니스 로직을 넣을 수 없습니다. 그래서! 보통 수동으로 바꾸죠"Manual/None" 으로 변경하고
상단메뉴 "Editor" -> Create NSManagedObject 합니다.
------
일단 여기까지 만들었으면
CoreDataManager를 만들어 사용합니다. 편하게 쓰려면 한곳에 몰아 넣어야죠
AppDelegate.swift
앱델리게이트에 선언 되어 있어야 한다.
//
// AppDelegate.swift
// CoreDataTest
//
// Created by jae hwan choo on 2020/09/24.
//
import UIKit
import CoreData
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: CoreDataManager.MODEL_NAME)
container.loadPersistentStores(completionHandler: { (storeDescription, 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)")
}
}
}
}
CoreDataManager.swift
아래와 같이 메니저 클래스를 만든다.
//
// CoreDataManager.swift
// CoreDataTest
//
// Created by jae hwan choo on 2020/09/24.
//
import UIKit
import CoreData
class CoreDataManager {
// MARK: - 변수
static let shared: CoreDataManager = CoreDataManager()
static let MODEL_NAME: String = "ErsModel"
static let MODEL_ENTITYNAME: String = "Contact"
let appDelegate: AppDelegate? = UIApplication.shared.delegate as? AppDelegate
lazy var context = appDelegate?.persistentContainer.viewContext
// MARK: - 저장
func setPeople(_ item: ContactVo, onSuccess: @escaping ((Bool) -> Void)) {
guard let context = context else {
return
}
if let entity: NSEntityDescription = NSEntityDescription.entity(forEntityName: CoreDataManager.MODEL_ENTITYNAME, in: context) {
if let user: Contact = NSManagedObject(entity: entity, insertInto: context) as? Contact {
user.name = item.name
user.age = item.age
//user.locationName = item.phone
}
// 실제 저장
contextSave { success in
onSuccess(success)
}
}
}
// MARK: 목록 내보내기
func getPeoples(ascending: Bool = false) -> [ContactVo] {
guard let context = context else {
return []
}
var models: [ContactVo] = [ContactVo]()
let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest<NSManagedObject>(entityName: CoreDataManager.MODEL_ENTITYNAME)
do {
if let fetchResult: [Contact] = try context.fetch(fetchRequest) as? [Contact] {
for item in fetchResult {
let people: ContactVo = ContactVo()
people.name = item.name ?? ""
people.age = item.age ?? ""
models.append(people)
}
}
} catch let error as NSError {
print("Could not fetch🥺: \(error), \(error.userInfo)")
}
return models
}
// MARK: 목록 전체 삭제
func deleteAllPeoples() {
guard let context = context else {
return
}
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: CoreDataManager.MODEL_ENTITYNAME)
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try context.execute(deleteRequest)
} catch let error as NSError {
print("Could not fetch🥺: \(error), \(error.userInfo)")
}
}
fileprivate func contextSave(onSuccess: ((Bool) -> Void)) {
do {
try context?.save()
onSuccess(true)
} catch let error as NSError {
print("Could not save🥶: \(error), \(error.userInfo)")
onSuccess(false)
}
}
}
ViewController.swift
아래와 같이 사용한다.
//
// ViewController.swift
// CoreDataTest
//
// Created by jae hwan choo on 2020/09/24.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
CoreDataManager.shared.setPeople(ContactVo("kim","16")) { (bool) in
// 저장성공
}
let datas = CoreDataManager.shared.getPeoples()
for item in datas {
print("이름 \(item.name)")
}
}
}
정상동작을 확인하고
이제 컬럼을 추가 해서 테스트 해본다.
...
...
...
그냥 된다. ㅠㅠ
방어 코드로 "AppDelegate.swift" 에서 Auto 마이그레이션 코드를 넣는다.
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: CoreDataManager.MODEL_NAME)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
// 코어 데이터가 변경 된 경우 마이그레이션 Auto 추가
let description = NSPersistentStoreDescription()
description.shouldInferMappingModelAutomatically = true
description.shouldMigrateStoreAutomatically = true
container.persistentStoreDescriptions.append(description)
return container
}()
일단
여기서 완료 하고 종료 한다.

댓글
댓글 쓰기