[iOS]<MemoApp> DB 기능 구현

RudinP·2023년 11월 16일
0

Study

목록 보기
118/227

DB 기능 구현

Core Data

  • iOS에서 데이터베이스를 구현할 때 사용

해당 강의에서는 초기에 이미 CoreData를 체크하고 생성하여 바로 진행되었지만 나는 빼먹은 관계로..^^ 직접 추가했다.

CoreData의 DataModel 생성

AppDelegate 수정

1. import CoreData

2. 메소드 추가

// MARK: - Core Data stack

    lazy var persistentContainer: NSPersistentContainer = {
        /*
         The persistent container for the application. This implementation
         creates and returns a container, having loaded the store for the
         application to it. This property is optional since there are legitimate
         error conditions that could cause the creation of the store to fail.
        */
        let container = NSPersistentContainer(name: "MemoApp")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                 
                /*
                 Typical reasons for an error here include:
                 * The parent directory does not exist, cannot be created, or disallows writing.
                 * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                 * The device is out of space.
                 * The store could not be migrated to the current model version.
                 Check the error message to determine what the actual problem was.
                 */
                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 {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }

xcdatamodeId

  • 메모가 어떤 형태로 저장되는지 설계도를 만드는 형식

Add Entity

  • 여기에서는 Memo 엔티티를 추가한다고 생각하면 된다.

Attribute

  • content: String, insertData: Date를 추가한다.

이제 content와 insertData는 Memo로 묶여 DB에 저장된다.

DataModel Inspector

목록의 엔티티를 선택 후 우측의 창을 표시하면 된다.


여기에서 엔티티와 관련된 옵션을 설정할 수 있다.
Codegen

  • CoreData를 사용할 때는 Entity를 Class로 다뤄야 한다.
  • 여기에 필요한 클래스는 자동으로 생성된다.
  • 생성되는 클래스의 이름은 Class-Name의 내용과 같다.

Attribute Inspector


현재 상태에서 빌드하게 되면 예전에 만들었던 Memo 클래스와 현재 DataModel에서 생성된 Memo 클래스가 충돌하게 된다.
현재는 dummyMemoList에 접근하는 코드가 많기 때문에 후에 수정해주고
일단 AppDelegate에 추가했던 CoreData와 관련된 코드를 수정해줄 것이다.

AppDelegate CoreData 코드 이동

  • CoreData와 관련된 코드를 추가했던 AppDelegate에서 해당 부분을 잘라내어 다른 파일로 옮긴다.

DataManager.swift 추가

  • 잘라냈던 코드를 여기로 이동한다.
  • 해당 클래스는 싱글톤으로 구현한다.

Context

  • 코어데이터에서 실행하는 대부분의 작업은 해당 객체가 담당
  • 기본적으로 생성되며, 커스텀도 가능.
  • 여기서는 기본생성된 context 사용

SceneDelegate.swift 수정

  • 처음부터 CoreData 사용을 체크했다면 여기서 AppDelegate의 saveContext 메소드를 호출하기 때문에 삭제해주어야한다. (나는 물론 나중에 추가해서 없다)
  • 위에서 싱글톤으로 구현했기 때문에 타입캐스팅이나 옵셔널 없이 호출 가능하다.

데이터베이스에서 Data 읽어오기(read)

  1. fetchRequest 생성
  2. 데이터 정렬(기본적으로 정렬되어있지 않음) -> sortDescriptor 생성 후 적용
  3. fetchRequest 실행
  • throws 를 사용하는 메소드는 do-catch 블록을 사용해야 함

이후 dummyData에 접근하는 부분들 수정

ViewWillAppear에서 fetch 실행

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        //tableView.reloadData()
        //print(#function)
        
        DataManager.shared.fetchMemo() //데이터로부터 메모 배열이 채워짐
        tableView.reloadData() //배열에 저장된 테이블을 기준으로 뷰 업데이트
    }

데이터베이스에 Data 쓰기(write)

DataManager.swift에 메소드 추가

  • 실제 메모를 저장하고 싶다면 메모 객체가 아닌, context를 저장해야 함
    • saveContext()가 자동으로 지원

메모를 저장하는 메소드에 작성한 메소드 호출

여기서는 ComposeViewController에 위치

그러나 메모를 표시하는 데이터의 기준인 memoList가 별도로 갱신되지 않았기 때문에, 앱을 재시동 하지 않는 한 테이블뷰에 바로 적용되지 않는다.

memoList 업데이트

  • ReloadData를 하기 전에 fetchMemo를 해도 되긴 하나, 성능적 이슈.
  • 그냥 addNewMemo 메소드에서 memoList에도 새로운 메모를 저장하면 됨.

실행 화면

메모가 정상적으로 추가됨을 확인

profile
곰을 좋아합니다. <a href = "https://github.com/RudinP">github</a>

0개의 댓글