3. Entity의 Name Attribute들을 Cell에 표시하기, SQLite Editor 다루기
TableView를 많이 다루어보지 않았다면, 준비 과정부터 꽤 어려웠을 것이다. (나는 어려웠다...ㅜ)
지금 하는 부분은, 이전 부분보다 더 쉽지는 않을 것이다.
CoreData가 처음이라면 새로운 것 투성이일 테니 말이다.
하지만, 차근차근히 읽어보고 이해 안가는 부분은 한번 더 읽고 따라해본다면 분명히 CoreData를 더 잘 이해할 수 있을 것이다.
먼저 CategoryViewController.swift 파일을 열자.
먼저 Categories 라는 변수를 만들고, 그 안에 방금 생성했던 Entity 의 이름으로 배열을 만들어주자!
Category라는 클래스를 배열로 생성한 것이다.
var categories = [Category]()
option 키를 누른채로, 방금 만든 변수를 클릭하면 NSManagedObject 클래스를 상속받는 인스턴스인 것을 확인할 수 있다.
만약에, NSManagedObject 타입이 아닌 다른 타입만 보인다면, Xcode를 종료했다 다시 켜보자.
나는 처음할 때 1시간을 헤매다가 그렇게 해서 해결했다... (어휴 엑스코드...ㅜㅜ)
아무튼 NSManagedObject 클래스가 무엇이냐? 하면, 우리가 저번에 이런 테이블을 만들었었는데,
여기서 붉은색으로 칠한 한 행이라고 보면 된다.
categories[0] = {project, red, true}
categrories[1] = {uni, green, flase}
...
이런 구조를 가지고 있는 것이다.
즉,
Category 라는 Entity는 저런 NSManagedObject 클래스 객체의 배열로 이루어져 있는 것이다.
이 부분을 반드시 이해하고 넘어가야, 앞으로 우리가 CoreData를 이용하는 것에 불편함이 없을 것이다!
이제 Context를 만들어줘야 한다.
Context는 CoreData에서 매우 매우 중요한 개념이다. (중요한게 연속해서 나오고있지만, 꼭 잘 알아두어야 한다!)
Context는 우리가 SQLite (우리가 CoreData를 통해 사용하는 DB)에 접근할 수 있도록 해준다.
자세한 설명은 Context 설명에서 자세히 해놓았기 때문에, 반드시 읽어봐야 한다.
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
context를 만들기 위해서는 다음과 같은 코드를 추가해줘야 한다.
여기서
UIApplication.shared.delegate as! AppDelegate 부분은 AppDelegate를 객체화 시킨 것이다.
만약에 우리가, AppDelegate.persistentContainer.viewContext 이렇게 사용한다면, AppDelegate 객체를 가져온 것이 아니라, AppDelegate Class를 가져와서 다루고 있는 것이다.
당연히 그 안에 Container가 있을리가 없다.
자, 우리는 이전에 AppDelegate에 persistentContainer를 만들어줬었다. 그 persistentContainer에서 viewContext를 뽑아서 우리가 사용하는 것이다.
이렇게 NSManagedObjectContext 타입의 해당 context를 만들었다.
하지만 현재 context는 만들어져있기만 하고 비어있는 상태이다.
이 context에 Entity의 Attribute 값들을 어떻게 categories 배열 변수로 가져올 수 있을까?
다음 함수를 CategoryViewController 클래스 내부에 추가해주자.
다음 함수는 Categoy Entity의 Raw들을 Categry 배열, 즉 categories로 넣어주는 기능을 한다.
func loadCategories(with request: NSFetchRequest<Category> = Category.fetchRequest()) {
do {
categories = try context.fetch(request)
} catch {
print("Error fetching Data from context \(error)")
}
tableView.reloadData()
}
이 함수는 언뜻 보기에 어떻게 동작하는지 이해하기 많이 어려울 것이다.
하나씩 차근차근 살펴보자.
맨 처음 함수의 매개변수를 보자.
request 는 NSFetchReqeust<Category> 라는 타입을 가지고, Category.fetchRequest() 함수를 통해 생성된다.
Category는 우리가 아까 만든 Entity의 Class로 NSManagedObject 클래스를 상속받는다.
이 클래스 안의 fetchRequest() 함수를 통해서 Category Entity를 대상으로 한 request를 생성하고,
context.fetch(request)를 통해 SQLite DB를 context로 가져오도록 요청하는 것이다.
마지막으로 tableView.reloadData() 는 이제 새롭게 categories로 정보를 가져왔으니,
새로고침을 해서 tableView에 반영을 해주는 역할을 한다.
자, 이제 어려운 건 정말 다 끝났다.
이제, categories의 값을 Cell에 나타내보자.
CategoryViewController 안에 다음 두개의 함수를 추가해주자.
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for: indexPath)
let category = categories[indexPath.row]
cell.textLabel?.text = category.name
return cell
}
tableView 함수에 대해서는 간략하게 설명하겠다.
먼저 맨 처음 함수는 Cell의 개수를 반환한다. 우리는 categories의 행 개수만큼 셀이 필요하기 때문에 categories.count를 반환하였다.
두번째는, CategoryCell의 항목 하나 하나에, 해당 indexPath.row 에 따라서 값을 집어넣어주는 역할을 한다.
우리의 Cell 의 textLabel에 DB에 있는 name을 하나씩 넣어주었다.
여기까지 하고 Build 후 시뮬레이터를 돌리면?
당연히 아무것도 뜨지 않는다. 우리는 아직 DB에 아무것도 넣지 않았다.
이제 Button에 DB에 무언가를 추가하는 기능을 추가할텐데,
그 전에 SQLite Workbench를 통해 DB를 살피고, 값을 수정하는 작업을 한번 해보겠다.
일단, 앱스토어를 켜서 SQLite 에디터 프로그램을 받아보자.
여러가지 앱이 있을 텐데, 나는 그 중에서 SQLiteFlow 라는 Editor를 받았다.
이 앱은 2주 동안 무료로 사용할 수 있으니, 괜찮은 기능을 잠깐 무료로 사용해보고 싶으면 이 앱을 받아도 될 것 같다.
꼭 이 앱이 아니라도 SQL Editor 프로그램이면 상관없다.
프로그램을 설치하고 나면 우리는 .sqlite 확장자 파일을 열어서 수정할 수 있다.
그럼 coreData로 관리되는 SQLite 파일은 어디에 있을까?
viewDidLoad 함수에 다음 코드를 추가한 후, 시뮬레이터를 실행시켜보자.
let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
print(paths[0])
우리의 SQLite 파일이 저장되어 있는 위치가 console에 찍힐 것이다.
터미널을 켜서 open 을 치고, 이 주소를 복사하고 enter를 누르면, 바로 finder에서 디렉토리를 열 수 있다.
하지만, 이 곳은 정확하게 sqlite 파일이 들어있는 곳은 아니다.
finder에서 Cmd + ↑ 를 눌러서 한단계 위로 올라간 후,
Library에서 Application Support 파일에 들어가면 우리가 찾는 sqlite 파일을 발견할 수 있다.
파일을 열면, 자동으로 에디터 프로그램이 실행될 것이다.
Data에 ZCATEGORY라고 젹혀있는 것이, 우리가 만든 Category Entity이다.
이곳에 들어가면 아직 아무것도 없을 것이다.
이 곳에서 ZNAME 즉, 우리가 만든 name Attrubute에 + 버튼을 눌러 원하는 값을 추가해준다.
나는 Project, Develop, 42Seoul, Home 이렇게 4개를 추가해주었다.
이제 마지막으로, 시뮬레이터를 실행핵서, 우리가 원하는 값이 들어왔는지를 확인해보자.
다음과 같이 잘 들어왔다!ㅎㅎ
정말 많은 것을 공부했는데, 가장 중요한 것은 무엇보다
loadCategories(with request: NSFetchRequest<Category> = Category.fetchRequest())
함수이다.
반드시 이 부분이 어떻게 작동하는지, 정확히 알고 넘어가야 CoreData를 문제없이 이용할 수 있을 것이다.
'iOS 개발 > CoreData' 카테고리의 다른 글
[CoreData] Relationship을 통해 Data를 관리하기 (0) | 2022.01.06 |
---|---|
[CoreData] Coredata 자체를 sort 할 수 있을까? (0) | 2021.11.17 |
[Core Data] Context를 이용해 Entity에 Attributes들을 추가, 삭제 (0) | 2021.09.08 |
[Core Data] TableView와 Navgation Cotroller을 임베디드 하기 (0) | 2021.09.07 |
[Core Data] Entity와 Attribute를 생성하는 방법 (0) | 2021.09.07 |
[Core Data] Context란? (0) | 2021.09.06 |
[Core Data] Entity Class 설정 - Codegen option 탐구 (0) | 2021.09.03 |
[애플 Document 번역] Core Data (0) | 2021.08.27 |