
DB를 생성하고, DB 속 데이터를 가져오는 코드를 짜보자!
먼저 아래의 project controller에서 Add Entity를 클릭한다.

새로운 Entity가 생성이 되었으면, 그 entity의 이름을 Memo로 설정을 한다.

그리고 Attribute에서 두개의 Attribute를 만들어 준다.

App Delegate를 보면 아래와 같이 Core Date Stack과 Core Data Saving support가 존재한다.

아래와 같이 주석을 제거해주고 두개의 파트를 잘라내기한다.

class DataManager {
static let shared = DataManager()
private init() {
// Singleton 싱글톤
}
var mainContext: NSManagedObjectContext{
return persistentContainer.viewContext
}
// 메모를 데이터베이스에서 읽어오는 코드를 작성해보자
var memoList = [Memo]()
func fetchMemo() {
let request: NSFetchRequest<Memo> = Memo.fetchRequest()
// 날짜를 내림차순으로 정렬해보자.
let sortByDateDesc = NSSortDescriptor(key: "insertDate", ascending: false)
request.sortDescriptors = [sortByDateDesc]
// 최종결과가 memoList에 저장이된다.
do {
memoList = try mainContext.fetch(request)
} catch{
print(error)
}
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "Memo")
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 {
// 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)")
}
}
}
}


그러게 다 만들고, 빌드를 실행해 보면, 에러발생가 발생하는 데 그 이유는 새롭게 만든 entity와 이미 만들어놨던 Model 속 Memo와 충돌이 일어났기 때문이다. 따라서 이제부터 전에 만들었던 Memo class를 수정해주자.



// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return DataManager.shared.memoList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
// Configure the cell...
let target = DataManager.shared.memoList[indexPath.row]
cell.textLabel?.text = target.content
cell.detailTextLabel?.text = formatter.string(for: target.insertDate)
return cell
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// 배열이 데이터에 채워지게 한다.
DataManager.shared.fetchMemo()
// tableView를 업데이트 하기
tableView.reloadData()
// tableView.reloadData()
}
// 참고 문헌//
Zedd님 블로그 -
https://zeddios.tistory.com/987
https://zeddios.tistory.com/989?category=682195
새로운 메모를 데이터 베이스에 저장하기
DataManager 클래스에 addNewMemo 함수를 생성해준다.
// 새로운 메모를 데이터 베이스에 저장하기
func addNewMemo(_ memo: String?){
// DataManager의 Memo이다.
let newMemo = Memo(context: mainContext)
newMemo.content = memo
// 현재 날자를 그대로 저장하기
newMemo.insertDate = Date()
saveContext()
}
@IBAction func save(_ sender: Any) {
// memoTextView에 있는 text를 newMemo로 저장!
guard let memo = memoTextView.text, memo.count > 0 else {
alert(message: "메모를 입력하세요")
return
}
// let newMemo = Memo(content: memo)
// Memo.dummyMemoList.append(newMemo)
// 데이터 베이스 저장하기!
DataManager.shared.addNewMemo(memo)
// NotificationCenter Post 설정하기
NotificationCenter.default.post(name: ComposeViewController.newMemoDidInsert, object: nil)
// 새 메모 창을 닫기
dismiss(animated: true, completion: nil)
}
그러나, 시뮬레이터를 실행해보면 데이터베이스에 저장이 되지만 메모리스트에 바로 나오지 않는다! 그 이유는 viewwillappear가 실행되지 않기 때문이다.(sheet로 되어있기에)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// 배열이 데이터에 채워지게 한다.
DataManager.shared.fetchMemo()
// tableView를 업데이트 하기
tableView.reloadData()
}
// 새로운 메모를 데이터 베이스에 저장하기
func addNewMemo(_ memo: String?){
// DataManager의 Memo이다.
let newMemo = Memo(context: mainContext)
newMemo.content = memo
// 현재 날자를 그대로 저장하기
newMemo.insertDate = Date()
// memoList에 바로 넣어주기
memoList.insert(newMemo, at: 0)
saveContext()
}