iOS

[iOS] Core Data (2) | CRUD

하이D:) 2023. 12. 10. 00:47

1편에서 작성한 core data 내용을 바탕으로 실제 뷰에 반영되도록 하는 예시를 만들어보려 한다. 추가로 CRUD를 해줄 수 있는 코어데이터 매니저를 만드는 방법까지!!

하다 보니 뭔가 아주 잘 맞는 케이스는 아니지만 최대한 단순하게 CoreData의 활용을 테스트해보고 싶었기에 소개한다.

 

[iOS] Core Data (1) | Persistence

[iOS] Core Data (2) | CRUD

[iOS] Core Data (3) | codegen(generating code) 이해해보자!

 

# 🥨 뷰 생성

table 뷰 만들어주고 row 추가, coredata에 저장된 데이터 확인, coredata에 저장된 데이터 삭제 할 수 있는 버튼 총 3개를 만들어준다.

여기까지는 뷰에 대한 영역이니까 이 글에서 까지 첨부할 필요는 없겠죵?

 

 

 

# 🥨 Core Data Model

Core Data Model생성을 위해 entity 추가해 주고 저장하고 싶은 attribute 추가하는 등 1편에서 나온 과정을 동일하게 해 주면 됩니다.

 

저는 Entity 이름은 Row로, 테이블뷰에 행이 추가됨에 따라 업데이트할 배열의 요소 개수를 number라는 attribute로 설

정해주었습니다!

 

 

# 🥨 CRUD

제가 이번에 해보고 싶었던 건 CRUD를 모두 할 수 있는 코어데이터 매니저를 만들고 활용하는 것이었는데요. 이렇게 싱글톤으로 사용할 수 있는 클래스 하나 만들어보았습니다. 사실 코어데이터 사용에 잘 맞는 예시는 아니어서 중간에 배열의 인덱스값으로 접근해서 업데이트해 주고 삭제해 주는 등의 코드가 있지만 하나의 클래스를 만들어서 테스트해 볼 수 있는 좋은 경험이었던 걸로 만족합니다!

import UIKit
import CoreData


class CoreDataManager {
    static var shared: CoreDataManager = CoreDataManager()
    
    //appDelegate에서 만들었던 Persistent Container으로부터 NSManagedObjectContext를 가져옴
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    lazy var context = appDelegate.persistentContainer.viewContext
    
    //Entity를 가져옴 - 내가 원하는 데이터들을 어떤 Entity에 attribute로 저장하고 싶은데!
    lazy var entity = NSEntityDescription.entity(forEntityName: "Row", in: context)
    
    // 값 삽입
    func insertRowNum(num : Int) {
        if let entity = entity {
            let row = NSManagedObject(entity: entity, insertInto: context)
            row.setValue(num, forKey: "number")
            
            saveToContext()
        }
    }
    
    //Create : 저장하기
    func saveToContext() {
        do {
            try context.save()
        } catch {
            print(error.localizedDescription)
        }
    }
    
    //Read : 불러오기
    func fetchRow() -> [Row] {
        do {
            let request = Row.fetchRequest()
            let results = try context.fetch(request)
            return results
        } catch {
            print(error.localizedDescription)
        }
        return []
    }
    
    //Update : 업데이트하기
    func updateRowNum(num : Int) {
        let fetchResults = fetchRow()
        if fetchResults.isEmpty { //아무것도 저장되지 않았으면 저장
            insertRowNum(num: num)
        } else { // 저장된 값이 있다면 그 값을 새로 업데이트
            fetchResults[0].number = Int16(num)
            saveToContext()
        }
    }
    
    //Delete : 삭제하기
    func deleteRowNum() {
        let fetchResults = fetchRow()
        if !fetchResults.isEmpty {
            context.delete(fetchResults[0])
            saveToContext()
        }
    }
    
    //우리가 실제 필요한 타입 형태로 받아주기
    func getRowNum() -> Int? {
        let fetchResults = fetchRow()
        
        if !fetchResults.isEmpty {
            return Int(fetchResults[0].number)
        }
        return nil
    }
}

 

 

 

그리고 '코어데이터 확인' 버튼을 눌렀을 때 print 해서 core data에 저장되어 있는 값을 확인할 수 있도록,

 '코어데이터 삭제' 버튼을 눌렀을 때 테이블뷰가 초기화될 수 있도록 코드를 짰다.

@objc func addBtnTapped() {
    self.listArray.append(listArray.count)
    self.tableView.reloadData() //항목추가하고 업데이트된 데이터로 테이블뷰 리로드
    
    CoreDataManager.shared.updateRowNum(num: listArray.count)
}

@objc func checkBtnTapped() {
    print("코어데이터에 저장되어 있는 값 -> ", CoreDataManager.shared.getRowNum())
}

@objc func delBtnTapped() {
    CoreDataManager.shared.deleteRowNum()
    self.listArray = [0,1,2,3,4]
    self.tableView.reloadData()
}