개발하는 동글 :]

[TIL],[TRY],[UIKit],[CoreData사용해보기][1] 본문

카테고리 없음

[TIL],[TRY],[UIKit],[CoreData사용해보기][1]

동글하다 2023. 9. 14. 22:41

1. CoreData의 사용을 위한 CoreDataManager 구현

CoreData사용을 위해 CoreDataManager를 만들어 보는 것을 시도해 보자!

CoreDataManager를 사용하기 위해 class를 만들고 싱글톤 패턴으로 만든 뒤 기본적인 프로퍼티를 만들어 보자.

final class CoreDataManager{
    
    static let shared = CoreDataManager()
    private init() {}
    
    private let appDelegate = UIApplication.shared.delegate as? AppDelegate
    
    private lazy var context = appDelegate?.persistentContainer.viewContext
    
    private let modelName: String = "Task"
    
}

2. Create

    // MARK: - [Create] 코어데이터에 데이터 생성하기
    func saveToDoData(title: String?, completion: @escaping () -> Void) {
        // 임시저장소 있는지 확인
        if let context = context {
            // 임시저장소에 있는 데이터를 그려줄 형태 파악하기
            if let entity = NSEntityDescription.entity(forEntityName: self.modelName, in: context) {

                // 임시저장소에 올라가게 할 객체만들기 (NSManagedObject ===> ToDoData)
                if let toDoData = NSManagedObject(entity: entity, insertInto: context) as? Task {

                    // MARK: - ToDoData에 실제 데이터 할당
                    toDoData.title = title
                    toDoData.id = UUID()
                    toDoData.createDate = Date.now
                    toDoData.isCompleted = false
                    toDoData.modifyDate = Date.now
                    appDelegate?.saveContext() // 앱델리게이트의 메서드로 해도됨
                }
            }
        }
        completion()
    }

3. Read

    // MARK: - [Read] 코어데이터에 저장된 데이터 모두 읽어오기
    func getToDoListFromCoreData() -> [Task] {
        var toDoList: [Task] = []
        // 임시저장소 있는지 확인
        if let context = context {
            // 요청서
            let request = NSFetchRequest<NSManagedObject>(entityName: self.modelName)
            
            do {
                // 임시저장소에서 (요청서를 통해서) 데이터 가져오기 (fetch메서드)
                if let fetchedToDoList = try context.fetch(request) as? [Task] {
                    toDoList = fetchedToDoList
                }
            } catch {
                print("가져오는 것 실패")
            }
        }
        
        return toDoList
    }

4. Update

    // MARK: - [Update] 코어데이터에서 데이터 수정하기 (일치하는 데이터 찾아서 ===> 수정)
    func updateToDo(task: Task, title: String, completion: @escaping () -> Void) {
        
        guard let id = task.id else {
            completion()
            return
        }
        
        // 임시저장소 있는지 확인
        if let context = context {
            // 요청서
            let request = NSFetchRequest<NSManagedObject>(entityName: self.modelName)
            // 단서 / 찾기 위한 조건 설정
            request.predicate = NSPredicate(format: "id = %@", id as CVarArg)

            do {
                // 요청서를 통해서 데이터 가져오기
                if let fetchedToDoList = try context.fetch(request) as? [Task] {
                    // 배열의 첫번째
                    if let targetToDo = fetchedToDoList.first {

                        // MARK: - ToDoData에 실제 데이터 재할당(바꾸기) ⭐️
                        targetToDo.title = title
                        targetToDo.modifyDate = Date.now
                        appDelegate?.saveContext() // 앱델리게이트의 메서드로 해도됨
                    }
                }
                completion()
            } catch {
                print("지우는 것 실패")
                completion()
            }
        }
    }
    // MARK: - [Update] 코어데이터에서 데이터 수정하기 (일치하는 데이터 찾아서 ===> 수정)
    func updateCompleted(task: Task, completion: @escaping () -> Void) {
        
        guard let id = task.id else {
            completion()
            return
        }
        
        // 임시저장소 있는지 확인
        if let context = context {
            // 요청서
            let request = NSFetchRequest<NSManagedObject>(entityName: self.modelName)
            // 단서 / 찾기 위한 조건 설정
            request.predicate = NSPredicate(format: "id = %@", id as CVarArg)

            do {
                // 요청서를 통해서 데이터 가져오기
                if let fetchedToDoList = try context.fetch(request) as? [Task] {
                    // 배열의 첫번째
                    if let targetToDo = fetchedToDoList.first {

                        // MARK: - ToDoData에 실제 데이터 재할당(바꾸기) ⭐️
                        targetToDo.isCompleted.toggle()
                        targetToDo.modifyDate = Date.now
                        appDelegate?.saveContext() // 앱델리게이트의 메서드로 해도됨
                    }
                }
                completion()
            } catch {
                print("지우는 것 실패")
                completion()
            }
        }
    }

5. Delete

    // MARK: - [Delete] 코어데이터에서 데이터 삭제하기 (일치하는 데이터 찾아서 ===> 삭제)
    func deleteToDo(task: Task, completion: @escaping () -> Void) {
        
        guard let id = task.id else {
            completion()
            return
        }
        
        // 임시저장소 있는지 확인
        if let context = context {
            // 요청서
            let request = NSFetchRequest<NSManagedObject>(entityName: self.modelName)
            // 단서 / 찾기 위한 조건 설정
            request.predicate = NSPredicate(format: "id == %@", id as CVarArg)

            do {
                // 요청서를 통해서 데이터 가져오기 (조건에 일치하는 데이터 찾기) (fetch메서드)
                if let fetchedToDoList = try context.fetch(request) as? [Task] {

                    // 임시저장소에서 (요청서를 통해서) 데이터 삭제하기 (delete메서드)
                    if let targetToDo = fetchedToDoList.first {
                        context.delete(targetToDo)
                        appDelegate?.saveContext() // 앱델리게이트의 메서드로 해도됨
                    }
                }
                completion()
            } catch {
                print("지우는 것 실패")
                completion()
            }
        }
    }

 

6. TIL

6.1 오늘의 회고

1. CoreData 의 CRUD를 구현을 완료하여 CoreDataManager를 완성한 후 ViewModel을 이용하여 Data를 사용하였다. 

2. CoreData의 구현을 완료하였지만 말 그대로 구현에만 목적을 둔 코드였기에 아직 코드를 이해하진 못하였다. 

3. Cell의 buttonTapped 메서드를 delegate를 이용하여 메서드를 controller에서 사용할 수 있었다. -> MVVM?을 위해?

4. 알고리즘을 오늘 풀지 않았다.. 자기 전에 한 문제 풀어보고 마무리 하자!

6.2 내일의 목표

1. CoreData 부분 코드 공부해서 이해해 보기 

2. 알고리즘 1문제

3. 계속해서 과제 클린코드로 짜보기